在一个数组中找到等于某个数的组合

方法1:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include <algorithm>
#include<iostream>
using namespace std;

void getResult(vector<int> a,int result) 
{
	sort(a.begin(),a.end());
	int nLen = a.size();
	for (int i = 0; i < nLen; i++) 
	{
		if (a[i] == result)
			cout<<a[i]<<endl;
		for (int j = i + 1; j < nLen; j++) 
		{
			if (a[i] + a[j] > result)
				break;
			if (a[i] + a[j] == result)
			{
				cout<<a[i]<<"+"<<a[j]<<endl;
			} 
			else 
			{
				for (int k = j + 1; k < nLen; k++)
				{
					if (a[i] + a[j] + a[k] > result)
						break;
					if (a[i] + a[j] + a[k] == result) 
					{
						cout<< a[i]<< "+"<<a[j]<<"+"<<a[k]<<endl;
					} 
					else
					{
						for (int l = k + 1; l < nLen; l++)
						{
							if (a[i] + a[j] + a[k] + a[l] > result)
								break;
							if (a[i] + a[j] + a[k] + a[l] == result)
								cout<<a[i]<<"+"<< a[j]<< "+" <<a[k]<<"+"<<a[l]<<endl;
							//else继续,有点复杂。 
						}
					}
				}
			}
		}
	}
}

void main() 
{
	vector<int> a;
	a.push_back(11);
	a.push_back(2);
	a.push_back(3);
	a.push_back(1);
	a.push_back(4);
	a.push_back(10);
	a.push_back(23);
	a.push_back(7);
	a.push_back(8);
	a.push_back(9);
	a.push_back(6);
	a.push_back(12);
	getResult(a,10);
	system("pause");
}

 

#include <list>
#include <vector>
using namespace std;

typedef vector<double> ListD;
typedef vector<ListD> ListLD;

//	给定一个数字数组,从这个数组中找出所有的组合,使组合中各数字相加等于一个给定数值  
//	nums = 给定数组  
//	num = 给定数值
//	index = 当前操作的数字在数组中的index
//	count = 存储所有组合的可能数
//	results = 存储所有组合的情况
void NumCount(double nums[], double num, int index, int &count,  ListLD &results,int NumLen)  
{				//当前操作的数字=给定数值      
	if (nums[index] == num)      
	{          //保存此组合         
		results[results.size() - 1].push_back(nums[index]);   
		count += 1;          //清空缓存并将除了此数之外的此组合的另外的数字存入缓存里  
		ListD TmpList;
		results.push_back(TmpList);         
		for (int i = 0; i < results[results.size() - 2].size() - 1; i++)          
		{             
			results[results.size() - 1].push_back(results[results.size() - 2][i]);         
		}         
		if (index ==  - 1)         
		{          
			return;         
		}          //进入到下一递归          
		NumCount(nums, num, index + 1, count, results,NumLen);     
	}      //大于给定数,跳过此数,进入到下一次递归   
	else if (nums[index] > num)     
	{         
		if (index == NumLen - 1)        
		{            
			return;        
		}          //此组合无效,跳到下一递归   
		NumCount(nums, num, index + 1, count, results,NumLen);      
	}			//小于给定数,则保存此数至缓存之后,给定数减去此数,然后进入下一次递归,之后将此数从缓存中删除    
	else    {         
		if (index == NumLen - 1)      
		{            
			return;       
		}          
		results[results.size() - 1].push_back(nums[index]);			//给定数减去此数        
		int tempNum = num - nums[index];							//进入到下一递归          
		NumCount(nums, tempNum, index + 1, count, results,NumLen);  //将此数从缓存中删除          
		ListD::iterator itr= results[results.size() - 1].begin();  
		itr+=(results[results.size() - 1].size() - 1); 
		results[results.size() - 1].erase(itr); 
		if (index < NumLen - 1)          
		{															//再跳过过此数,给定数不变,进入到下一次递归             
			NumCount(nums, num, index + 1,count,results,NumLen);        
		}     
	}  
} 

int main()
{
	double test[10] = {1,2,3,4,5,6,7,8,9,10};
	ListLD testList;
	int a = 0,b=0;
	NumCount(test,10,a,b,testList,10);
	return 0;
}

此代码运行出错,我根据C#翻译的,原文地址

http://sumice.name/A/Index/86


 

可以使用回溯法来解决这个问题。具体实现步骤如下: 1. 定义一个组来存储组合结果 2. 定义一个变量来记录组合 3. 编写回溯函,函需要传入目标和、当前和、起始位置、当前组合结果、组合和阈值等参 4. 在回溯函中,首先判断当前和是否等于目标和,如果是,则将当前组合结果加入数组中,并将组合加1,如果组合已经达到阈值,则直接返回 5. 如果当前和小于目标和,则从起始位置开始遍历组,将当前位置的加入当前组合结果中,并递归调用回溯函,起始位置为当前位置的下一个位置,当前和为原来的基础上加上当前位置的 6. 回溯时需要将当前位置的从当前组合结果中删除 下面是 Java 代码实现: ```java import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class CombinationSum { public static List<List<Integer>> combinationSum(int[] candidates, int target, int limit) { List<List<Integer>> res = new ArrayList<>(); List<Integer> cur = new ArrayList<>(); dfs(candidates, target, 0, cur, res, limit); return res; } private static void dfs(int[] candidates, int target, int start, List<Integer> cur, List<List<Integer>> res, int limit) { if (target == 0) { res.add(new ArrayList<>(cur)); if (res.size() == limit) { return; } } else if (target > 0) { for (int i = start; i < candidates.length; i++) { cur.add(candidates[i]); dfs(candidates, target - candidates[i], i + 1, cur, res, limit); cur.remove(cur.size() - 1); if (res.size() == limit) { return; } } } } public static void main(String[] args) { int[] candidates = {2, 3, 6, 7}; int target = 7; int limit = 2; List<List<Integer>> res = combinationSum(candidates, target, limit); System.out.println(Arrays.toString(res.toArray())); } } ``` 在上面的代码中,我们定义了一个 `combinationSum` 函来实现组合求和的功能。该函接收一个目标和一个组和一个组合阈值作为参,并返回符合条件的组合列表。 在 `dfs` 函中,我们首先判断当前和是否等于目标和,如果是,则将当前组合结果加入数组中,并将组合加1,如果组合已经达到阈值,则直接返回。如果当前和小于目标和,则从起始位置开始遍历组,将当前位置的加入当前组合结果中,并递归调用回溯函,起始位置为当前位置的下一个位置,当前和为原来的基础上加上当前位置的。回溯时需要将当前位置的从当前组合结果中删除。 最后,我们在 `main` 函中调用 `combinationSum` 函,并输出结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值