JAVA 在数组中求出所有和等于特定值的可能组合

 给定一个数组和一个定值。求出该数组中任意取几个数使其和等于该给定值,输出所有的组合情况,同一组合只输出一次。


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



  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值