C++ 我可以停止执行其他递归树分支吗?
我得到了一个整数向量和一个和,如果这个和可以从这个向量中的任何元素组合生成,我需要返回这个组合。如果可能有多个这样的组合,我可以返回任何一个 比如说, sum=20,vector={6,25,8},我们可以把86打印成8+6+6=20 sum=10,vector={4,6,7},我们可以将64打印为6+4=10 sum=15,vector={8,4,5},我们可以把5打印成5+5+5=15 问题:上面的最后两个例子很好,但第一个却不行。原因是,如果您为第一个示例绘制递归树,然后根据我的代码,您会得到C++ 我可以停止执行其他递归树分支吗?,c++,recursion,dynamic-programming,C++,Recursion,Dynamic Programming,我得到了一个整数向量和一个和,如果这个和可以从这个向量中的任何元素组合生成,我需要返回这个组合。如果可能有多个这样的组合,我可以返回任何一个 比如说, sum=20,vector={6,25,8},我们可以把86打印成8+6+6=20 sum=10,vector={4,6,7},我们可以将64打印为6+4=10 sum=15,vector={8,4,5},我们可以把5打印成5+5+5=15 问题:上面的最后两个例子很好,但第一个却不行。原因是,如果您为第一个示例绘制递归树,然后根据我的代码,您会
标志
变量true,因为在同一父节点下存在多个目标总和
=0的基本情况。因此,最后一个示例打印8 6
我的问题是,因为我只需要打印任何可能的组合,加起来就是targetSum
,我可以跳过递归树的其他分支吗?基本上,一旦我们找到了targetSum
=0的基本情况,我们就进入树并打印出序列?可能吗?(我已尝试为此使用stackCount
,但如果找到总计为targetSum
的序列,则它仅会阻止根节点的右侧子节点执行。)如果没有,请告诉我如何或如何修改此代码,以使其正常工作
#include <iostream>
#include <vector>
#include <map>
using namespace std;
bool howSum(int &targetSum, vector<int> &elementVector, vector<int> &howSumVector, map<int, bool> &memo, int &stackCount) {
stackCount++;
if (memo.find(targetSum) != memo.end())
return memo[targetSum];
else if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else {
for (auto i : elementVector) {
int remainder = targetSum - i;
bool flag = howSum(remainder, elementVector, howSumVector, memo, stackCount);
stackCount--;
if (flag) {
howSumVector.push_back(i);
memo[targetSum] = true;
} else if(memo.find(targetSum) == memo.end())
memo[targetSum] = false;
if(stackCount == 1 && !howSumVector.empty())
return true;
}
return memo[targetSum];
}
}
int main() {
int stackCount = 0;
int sum = 20; // test cases 20,10,15
map<int, bool> memo;
vector<int> elements = {6,25,8}; // test cases {6,25,8},{4,6,7},{8,4,5}
vector<int> workingBench = {};
howSum(sum, elements, workingBench, memo, stackCount);
for (auto i : workingBench)
cout << i << " ";
}
#包括
#包括
#包括
使用名称空间std;
布尔豪森(整数和目标数、向量和元素向量、向量和豪森向量、地图和备忘录、整数和堆栈计数){
stackCount++;
if(memo.find(targetSum)!=memo.end())
返回备忘录[目标金额];
else if(targetSum==0)
返回true;
否则如果(targetSum<0)
返回false;
否则{
用于(自动i:elementVector){
整数余数=targetSum-i;
bool标志=howSum(余数、元素向量、howSumVector、备注、堆栈计数);
堆栈计数--;
国际单项体育联合会(旗){
推回(i);
备注[目标金额]=真;
}else if(memo.find(targetSum)=memo.end())
备注[目标金额]=错误;
if(stackCount==1&&!howSumVector.empty())
返回true;
}
返回备忘录[目标金额];
}
}
int main(){
int stackCount=0;
int sum=20;//测试用例20,10,15
地图备忘录;
向量元素={6,25,8};//测试用例{6,25,8},{4,6,7},{8,4,5}
向量工作台={};
howSum(总和、元素、工作台、备忘录、堆栈计数);
用于(自动i:工作台)
cout当您找到匹配项时,您需要结束递归,在这种情况下,当flag==true
时
if (flag) {
howSumVector.push_back(i);
memo[targetSum] = true;
return true; // We found a match! Stop searching!
}
编辑:
您没有正确使用memo。因为您只需要一个可能的解决方案,所以不需要跟踪某个组合是否有效
您想要的是跟踪您以前是否有相同的余数。如果有,您只需立即中止搜索即可
如果目标是20
,并且您有一些数字组合,这些数字的余数为5,那么无论是什么数字组合使我们达到了这一目标
假设我们无法从15到达目标,那么如果我们以不同的数字组合再次到达15,我们已经知道我们永远无法从15到达目标,因此我们可以中止那里的搜索
如果我们可以从15年达到目标,我们已经找到了解决方案,递归已经结束,所以我们也不关心结果
下面是一个经过修改的完整示例
#include <iostream>
#include <vector>
#include <set>
using namespace std;
bool howSum(int targetSum, const vector<int> &elementVector, vector<int> &howSumVector, set<int> &memo) {
if (memo.find(targetSum) != memo.end()) {
return false;
}
memo.insert(targetSum);
if (targetSum == 0) {
return true;
} else if (targetSum < 0) {
return false;
} else {
for (auto i : elementVector) {
bool flag = howSum(targetSum - i, elementVector, howSumVector, memo);
if (flag) {
howSumVector.push_back(i);
return true;
}
}
return false;
}
}
int main() {
int sum = 20; //20,10,15
set<int> memo;
vector<int> elements = {6,25,8}; // {6,25,8},{4,6,7},{8,4,5}
vector<int> workingBench = {};
howSum(sum, elements, workingBench, memo);
if (workingBench.empty())
cout << "not possible";
else
for (auto i : workingBench)
cout << i << " ";
}
#包括
#包括
#包括
使用名称空间std;
布尔豪森(整数目标和、常量向量和元素向量、向量和豪森向量、集合和备注){
if(memo.find(targetSum)!=memo.end()){
返回false;
}
备注。插入(targetSum);
如果(targetSum==0){
返回true;
}否则如果(targetSum<0){
返回false;
}否则{
用于(自动i:elementVector){
bool flag=howSum(targetSum-i,elementVector,howSumVector,memo);
国际单项体育联合会(旗){
推回(i);
返回true;
}
}
返回false;
}
}
int main(){
int sum=20;//20,10,15
设置备忘录;
向量元素={6,25,8};//{6,25,8},{4,6,7},{8,4,5}
向量工作台={};
howSum(总和、要素、工作台、备忘录);
if(workingBench.empty())
不能我的最终代码-
#include <iostream>
#include <vector>
#include <map>
using namespace std;
bool howSum(int &targetSum, vector<int> &elementVector, vector<int> &howSumVector, map<int, bool> &memo) {
if (memo.find(targetSum) != memo.end())
return memo[targetSum];
else if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else {
for (auto i : elementVector) {
int remainder = targetSum - i;
bool flag = howSum(remainder, elementVector, howSumVector, memo);
if (flag) {
howSumVector.push_back(i);
memo[targetSum] = true;
return true;
} else if (memo.find(targetSum) == memo.end()) // if targetSum is NOT in memo
memo[targetSum] = false;
}
return false;
}
}
int main() {
int sum = 20; //20,10,15
map<int, bool> memo;
vector<int> elements = {6,25,8}; // {6,25,8},{4,6,7},{8,4,5}
vector<int> workingBench = {};
howSum(sum, elements, workingBench, memo);
if (workingBench.empty())
cout << "not possible";
else
for (auto i : workingBench)
cout << i << " ";
}
#包括
#包括
#包括
使用名称空间std;
布尔豪森(整数与目标和、向量与元素向量、向量与豪森向量、地图与备忘录){
if(memo.find(targetSum)!=memo.end())
返回备忘录[目标金额];
else if(targetSum==0)
返回true;
否则如果(targetSum<0)
返回false;
否则{
用于(自动i:elementVector){
整数余数=targetSum-i;
bool标志=howSum(余数、元素向量、howSumVector、备注);
国际单项体育联合会(旗){
推回(i);
备注[目标金额]=真;
返回true;
}else if(memo.find(targetSum)=memo.end())//如果targetSum不在memo中
备注[目标金额]=错误;
}
返回false;
}
}
int main(){
int sum=20;//20,10,15
地图备忘录;
向量元素={6,25,8};//{6,25,8},{4,6,7},{8,4,5}
向量工作台={};
howSum(总和、要素、工作台、备忘录);
if(workingBench.empty())
有趣的是,我也不需要再跟踪堆栈计数了。@Divyansuvarma我做了一些编辑,以解决您使用memo
和一些其他细节的问题。“您没有正确使用memo
。”对于这个确切的问题陈述,我同意您的这个修改后的解决方案是简单而简单的