哥们让我帮他写一个段代码,要求一组Double型的数随机取N个求和等于给定的一个数W,把所以可能都取出来。因为不需要重复的,所以是一个组合问题。我就写下面的代码。
public class assemble { //拿值的数组 private Double[] arr ; //给定的目标数 private Double W ; //取数的个数 private int m; //结果集,存的是数在数组中的位置 private Set<Set<Integer>> result = new HashSet<Set<Integer>>(); assemble(Double[]arr,Double W,int m){ this.arr=arr; this.W=W; this.m=m; } //控制取数次数 public Set<Set<Integer>> init() { m -= 1; for (int x = 0; x < arr.length; x++) { if (arr[x] < W) { Set<Integer> set = new HashSet<Integer>(); set.add(x); iteration(set, m); } } return result; } //遍历把值存入set中 public Set<Integer> ergodicSet(int y,Set<Integer> set){ Set<Integer> newset = new HashSet<Integer>(); newset.add(y); Iterator<Integer> it2 = set.iterator(); while (it2.hasNext()) { int i = it2.next(); newset.add(i); } return newset; } //递归取数的位置 public void iteration(Set<Integer> set, int m) { m -= 1; Iterator<Integer> it = set.iterator(); Double v = 0.0; while (it.hasNext()) { int i = it.next(); v += arr[i]; } for (int y = 0; y < arr.length; y++) { if (!set.contains(y)) { //是否是最后一次取值 if (m != 0) { //小于目标数把数的位置存入set if (arr[y] + v < W) { Set<Integer> newset=ergodicSet(y,set); iteration(newset, m); } } else { //最后一次等于目标数把数的位置存入result if (arr[y] + v == W) { Set<Integer> newset=ergodicSet(y,set); result.add(newset); } } } } } public static void main (String args[]){ Double [] array={1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; assemble ass=new assemble(array,3.0,3); Set<Set<Integer>> r=new HashSet<Set<Integer>>(); r=ass.init(); Iterator<Set<Integer>> iter = r.iterator(); //打出所以可能 while (iter.hasNext()) { Set<Integer> z=iter.next(); Iterator<Integer> zit = z.iterator(); while (zit.hasNext()) { System.out.print(zit.next()); } System.out.println(); } } }
反正结果正确,没注意是不是写的够优。