C++ 我可以停止执行其他递归树分支吗?

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 问题:上面的最后两个例子很好,但第一个却不行。原因是,如果您为第一个示例绘制递归树,然后根据我的代码,您会

我得到了一个整数向量和一个和,如果这个和可以从这个向量中的任何元素组合生成,我需要返回这个组合。如果可能有多个这样的组合,我可以返回任何一个

比如说,

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
。”对于这个确切的问题陈述,我同意您的这个修改后的解决方案是简单而简单的