给定一个数组和一个定值。求出该数组中任意取几个数使其和等于该给定值,输出所有的组合情况,同一组合只输出一次。
public class SumOfArray {
public static void foo(int[] data,int sum) {
//快速排序,打印排序结果
QuickSort.sort(data, 0, data.length-1);
System.out.print("快排结果:\n");
for(int i=0;i<data.length;i++)
{
System.out.print(data[i] + " ");
}
System.out.print("\n");
//去除数组中比和值大的元素
int length=0;
for(;length<data.length &&data[length]<=sum;length++);
int[] values=new int[length];
System.out.print("去除大于给定值的数组:\n");
for(int i=0;i<length;i++)
{
values[i]=data[i];
System.out.print(values[i] + " ");
}
System.out.print("\n");
Stack<Integer> stack = new Stack<Integer>(); //存放可能组合的序号
int tempSum=0; // 堆栈中元素和
int m=0;
System.out.printf("所有和为%d的组合:\n",sum);
while(m<length)
{
if(tempSum+values[m]<sum) //堆栈中元素和加上当前值小于给定值,则将该值序号加入堆栈
{
stack.push(m);
tempSum=tempSum+values[m];
m++;
}
else
{
if(tempSum+values[m]==sum)
{
//输出一种组合
for(int i=0;i<stack.size();i++)
{
System.out.print(values[stack.get(i)] + " ");
}
System.out.print(values[m] + "\n");
}
if(stack.size()>0)
{
int n=stack.pop();
tempSum=tempSum-values[n];
m=n+1;
for(;values[m]==values[n];m++); //下一个元素如果等于从堆栈的弹出值,则跳过。避免重复组合
}
else {
break;
}
}
}
}
}
public class QuickSort {
public static void sort(int[] data, int left, int right) {
int dp;
if (left < right) {
dp = partition(data, left, right);
if (left < dp - 1)
sort(data, left, dp - 1);
if (dp + 1 < right)
sort(data, dp + 1, right);
}
}
static int partition(int data[], int left, int right) {
int pivot = data[left];
while (left < right) {
while(left<right && data[right]>=pivot)
right--;
if(left<right)
data[left++]=data[right];
while(left<right && data[left]<=pivot)
left++;
if(left<right)
data[right--]=data[left];
}
data[left] = pivot;
return left;
}
}
main函数测试:
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] data = new int[30];
for (int i = 0; i < data.length; i++)
data[i] = (int) (Math.random() * 20+1);
SumOfArray.foo(data, 18);
}
测试结果: 12 8 8 14 1 16 16 12 2 9 3 18 19 14 20 19 7 11 2 1
***********************
快排结果:
1 1 2 2 3 7 8 8 9 11 12 12 14 14 16 16 18 19 19 20
去除大于给定值的数组:
1 1 2 2 3 7 8 8 9 11 12 12 14 14 16 16 18
所有和为18的组合:
1 1 2 2 3 9
1 1 2 2 12
1 1 2 3 11
1 1 2 14
1 1 7 9
1 1 8 8
1 1 16
1 2 3 12
1 2 7 8
1 3 14
1 8 9
2 2 3 11
2 2 14
2 7 9
2 8 8
2 16
3 7 8
7 11
18