请问怎么从很多1-10的数字中挑选出一组和为100的组合?

ZZZ5512536 2011-11-18 11:20:59
请大家指教~~~能实现功能就行,当然效率越高就更好了,谢谢!
...全文
540 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
handsomebigdog 2011-11-22
  • 打赏
  • 举报
回复

import java.util.Vector;

public class SelectCombinations
{
private int [] data;
private int condition;
private Vector<String> vresult = new Vector<String>();

public SelectCombinations(int [] source, int cond)
{
data = source;
condition = cond;
}

private void selectCombination(int startIndex, int cout, int sum, String expression)
{
if (cout==1 && sum+data[startIndex]==condition)
{
String s = expression + "+" + data[startIndex] + "=" + condition;
vresult.add(s.substring(1));
return;
}
for (int i=startIndex+1; i<data.length; i++)
if (i+cout-1 <= data.length)
selectCombination(i, cout-1, sum+data[startIndex], expression + "+" + data[startIndex]);
else
break;
}

public void selectAllCombinations()
{
for (int startIndex=0; startIndex<data.length; startIndex++)
for (int cout=1; cout<=data.length-startIndex; cout++)
selectCombination(startIndex, cout, 0, "");
}

public void display()
{
System.out.print("从数组{");
for (int i=0 ; i<data.length; i++)
if (i != data.length-1)
System.out.print(data[i]+ ",");
else
System.out.print(data[i]+ "}");
System.out.println("里选出和等于" + condition + "的组合有");
for (int i=0; i<vresult.size(); i++)
System.out.println("第" + i + "种结果:" + vresult.get(i));
}

public static void main(String [] args)
{
int [] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};//自行添减
int cond = 48;//sum条件
SelectCombinations sc = new SelectCombinations(arr, cond);
sc.selectAllCombinations();
sc.display();
}
}
handsomebigdog 2011-11-22
  • 打赏
  • 举报
回复
我不会贪心算法,不过你可以试试这个

import java.util.Vector;

public class SelectCombinations
{
private int [] data;
private int condition;
private Vector<String> vresult = new Vector<String>();

public SelectCombinations(int [] source, int cond)
{
data = source;
condition = cond;
}

private void selectCombination(int startIndex, int cout, int sum, String expression)
{
if (cout==1 && sum+data[startIndex]==condition)
{
String s = expression + "+" + data[startIndex] + "=" + condition;
vresult.add(s.substring(1));
return;
}
for (int i=startIndex+1; i<data.length; i++)
if (i+cout-1 <= data.length)
selectCombination(i, cout-1, sum+data[startIndex], expression + "+" + data[startIndex]);
else
break;
}

public void selectAllCombinations()
{
for (int startIndex=0; startIndex<data.length; startIndex++)
for (int cout=1; cout<=data.length-startIndex; cout++)
selectCombination(startIndex, cout, 0, "");
}

public void display()
{
System.out.print("从数组{");
for (int i=0 ; i<data.length; i++)
if (i != data.length-1)
System.out.print(data[i]+ ",");
else
System.out.print(data[i]+ "}");
System.out.println("里选出和等于" + condition + "的组合有");
for (int i=0; i<vresult.size(); i++)
System.out.println("第" + i + "种结果:" + vresult.get(i));
}

public static void main(String [] args)
{
int [] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};//自行添减
int cond = 48;//sum条件
SelectCombinations sc = new SelectCombinations(arr, cond);
sc.selectAllCombinations();
sc.display();
}
}
hzc543806053 2011-11-18
  • 打赏
  • 举报
回复
class test
{
public static void main(String[] args)
{
int sum=0;
for(i=1;i<=10;i++
{
for(j=1;j<=10;j++)
{
for(k=1;k<=10;k++)
{
.... //要有10个for循环以上
sum = i + j + k + ... ;
if(sum==100)
System.out.println(i+" "+j+" "+k+" "+...);
}

}
}
}
}
hzc543806053 2011-11-18
  • 打赏
  • 举报
回复
比如说:for循环

class test
{
public static void main(String[] args)
{
int sum=0;
for(i=1;i<=10;i++
{
for(j=1;j<=10;j++)
{
for(k=1;k<=10;k++)
{
.... //要有10个for循环以上
sum = i + j + k + ... ;
if(sum==100)
System.out.println(i+" "+j+" "+k+" "+...);
}

}
}
}
}
打油的程序员 2011-11-18
  • 打赏
  • 举报
回复
讲效率的话,应该是贪心法最高。
你可以模仿“背包问题”的贪心法
Mourinho 2011-11-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hzc543806053 的回复:]

Java code
class test
{
public static void main(String[] args)
{
int sum=0;
for(i=1;i<=10;i++
{
for(j=1;j<=10;j++)
{
……
[/Quote]

我了个去,要是给你100个数组成10000是不是要写10000个for?
qybao 2011-11-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zzz5512536 的回复:]
算法我一塌糊涂啊。。能贴出相关代码嘛?现在还有其他事情没做,时间又紧迫,头大啊
另外忘说了,本来题目是这样的:
从一堆分值不同的题从随机抽取组成总值为100的试卷。所以被抽过一次了的就不能再被选中了。
[/Quote]
以前好像给你回答过一次

http://topic.csdn.net/u/20111108/15/9a1e8642-b4c1-4d0c-85aa-c3d99b485015.html
junerkele 2011-11-18
  • 打赏
  • 举报
回复
贪心算法不知道可行,这个丢的时间太长,抽出总和小于100的是可以,呵呵








--signature--------------------
http://www.lunwenwa.com/
ZZZ5512536 2011-11-18
  • 打赏
  • 举报
回复
算法我一塌糊涂啊。。能贴出相关代码嘛?现在还有其他事情没做,时间又紧迫,头大啊
另外忘说了,本来题目是这样的:
从一堆分值不同的题从随机抽取组成总值为100的试卷。所以被抽过一次了的就不能再被选中了。
qybao 2011-11-18
  • 打赏
  • 举报
回复
如果只求一种结果,用回溯法就可以了
给个例子,只求一种解
本例子可修改求多种解,即把每次找到结果后并不退出循环,而是保存到一个List<List<Integer>>结果中,直到无法找到结果为止,这里偷懒就不做了
import java.util.*;
public class Test {
public static void main(String[] args) throws Throwable {
List<Integer> list = getCombine(Arrays.asList(new Integer[]{2,4,5,6,7,9}), 100);
if (list.size() > 0) {
System.out.println(list);
} else {
System.out.println("no result.");
}
}

public static List<Integer> getCombine(List<Integer> list, int sum) {
List<List<Integer>> used = new ArrayList<List<Integer>>(); //记录某个位置用过的数字
List<Integer> result = new ArrayList<Integer>(); //结果
Collections.sort(list); //多个数字从小到大排列好
int index = 0;
int remain = sum, last;
while (remain > 0) { //剩余的和>0一直循环
index++;
if (used.size() < index) {used.add(new ArrayList<Integer>());}

List<Integer> valid = new ArrayList<Integer>(list); //有效数字
valid.removeAll(used.get(index-1)); //去掉某个位置使用过的数字
if (valid.size() == 0) { //如果都使用过了
if (index == 1) {
break;
}
used.get(index-1).clear(); //当前位置使用过的数字清空
if (result.size() > 0) {
last = result.remove(result.size()-1); //结果的最后一个数字去掉
remain += last; //把去掉的数字还原回原来的和
used.get(index-2).add(last); //当前位置的上一个位置追加使用过的数字
}
index -= 2;
continue;
}

last = valid.get(valid.size()-1); //获取有效数字的最大数字
//last = valid.get((int)(Math.random()*valid.size())); //随即获取有效数字
result.add(last); //获取的数字保存到结果集
remain -= last; //剩余的和
if (list.contains(remain)) { //如果剩余的和刚好也在数字集合中
result.add(remain); //则获取结果,并退出循环
break; //获取结果后可以不退出,继续寻找下一种结果,当然要做一些额外的恢复处理
} else if (remain < list.get(0)) { //如果剩余的和没法用集合的数字求和得到
remain += last; //则恢复剩余的和
result.remove(result.size()-1);//并把结果集最后的一个数组去掉
index--;
used.get(index).add(last); //并在当前位置记录使用过的数字
}
}

return result;
}
}
rocky225 2011-11-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 k3108001263 的回复:]

讲效率的话,应该是贪心法最高。
你可以模仿“背包问题”的贪心法
[/Quote]
我也是这样想,用下栈,嘻嘻

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧