给定一个数组,求数组中所有元素的可能组合(每个元素只出现一次),使其和等于给定数的解决办法

只求一个组合可以采用背包问题的思路,求所有组合的话,背包问题可能就不太适用了。

这里面采用暴力搜索+剪枝,具体是先对给定的数组进行排序,在求解的深度优先搜索过程

中,如果出现中间的求和结果大于预先给定的数,那么就不用继续搜索了(因为后面的元素都大于

等于当前的元素,不用再往后搜索了)。

以前也写过类似的程序,但只是针对具体问题的,

这里修改了下,

给出一个比较通用的代码:

public void find(int total,int []a) { if(a == null || a.length == 0) return; //排序是为了在深搜时可以进行剪枝 java.util.Arrays.sort(a); final int length = a.length; int []resultArray = new int[length]; for(int i=0;i<length;i++) { resultArray[i] = 0; } resultArray[0] = 1; int count = 0; // int t_count = 0; int arrayLocationIndex = 1;//标识resultArray中有多少个位置不为0 int tempNumber = 1;//标志当前已经到了resultArray的哪个下标 while(true) { // t_count++;if(t_count == 100) break; if(resultArray[0] == length+1) break;//循环跳出条件 int temp = 0; //for循环计算当前结果 // System.out.println(java.util.Arrays.toString(resultArray)); for(int i=0;i<resultArray.length;i++) { if(resultArray[i] != 0) { temp += a[resultArray[i]-1]; } } if(temp == total) {//得到了一个符合条件的结果 count++; //打印这个结果的内容 System.out.println(java.util.Arrays.toString(resultArray)); for(int i=0;i<resultArray.length;i++) { if(resultArray[i] != 0) { System.out.print(a[resultArray[i]-1]+" "); } } System.out.println(); if(arrayLocationIndex == 1) { //这种情况下数组中只有一个元素,那么把它加1(a中的下标) resultArray[0]++; }else { //把resultArray中最后一个不为0的置为0,同时把倒数第二个元素+1 resultArray[tempNumber] = 0; resultArray[arrayLocationIndex++]++; tempNumber = arrayLocationIndex; } } if(temp < total) { // System.out.println("temp < total arrayLocationIndex ["+arrayLocationIndex+"]tempNumber["+tempNumber+"]"); // System.out.println(java.util.Arrays.toString(resultArray)); if(tempNumber < length) { //继续添加下一个 tempNumber++; resultArray[arrayLocationIndex] = tempNumber; arrayLocationIndex++; }else { //已经到a的最后了,回退 if(resultArray[arrayLocationIndex-1] == length) break; resultArray[arrayLocationIndex-1] = 0; resultArray[arrayLocationIndex-2]++; tempNumber = arrayLocationIndex; } // System.out.println(java.util.Arrays.toString(resultArray)); } if(temp > total) { // System.out.println("temp > total arrayLocationIndex ["+arrayLocationIndex+"]tempNumber["+tempNumber+"]"); // System.out.println(java.util.Arrays.toString(resultArray)); if(tempNumber == 1){ // System.out.println("tempNumber == 1"); break; } if(tempNumber == length) { //到a数组的最后了,回退 resultArray[arrayLocationIndex-2]++; tempNumber = resultArray[arrayLocationIndex-2]; resultArray[arrayLocationIndex-1]=0; arrayLocationIndex--; }else { //类似于temp < total分支 resultArray[arrayLocationIndex-1] = 0; resultArray[arrayLocationIndex-2]++; tempNumber = resultArray[arrayLocationIndex-2]; arrayLocationIndex--; } // tempNumber = resultArray[arrayLocationIndex-1]+1; // System.out.println(java.util.Arrays.toString(resultArray)); } } System.out.println(count); }

你可能感兴趣的:(null)