【问题标题】:Print accumulated sums in C++ in a recursive function在递归函数中打印 C++ 中的累积和
【发布时间】:2014-03-31 01:57:49
【问题描述】:

所以我有这个函数和这些全局变量。

int recurs=0;
std::string sign="";
void count2(int k, std::vector<int> d, int total, int temp, bool flag, unsigned short int pos){
    std::string mas="+";
    std::string menos="-";
    if(pos==(d.size())){
        total+=temp;
        if(total==k){
            result++;
            std::cout << sign << "=" << k<<std::endl;
            str="";
        }
        recurs++;
        return;
    }    
    //Sum sign.
    sign=sign.substr(0,sign.size()-recurs*2);
    sign.append(mas+=std::to_string(d[pos]));
    count2(k,d,total+temp,+d[pos],true,pos+1);  
    //Rest sign
    sign=sign.substr(0,sign.size()-recurs*2);
    sign.append(menos+=std::to_string(d[pos]));
    count2(k,d,total+temp,-d[pos],false,pos+1);  
    //Append digit
    if(flag==true)
        count2(k,d,total,10*temp-d[pos],true,pos+1);
    else
        count2(k,d,total,+10*temp+d[pos],false,pos+1);
}

函数调用如下: count2(6,{1,2,3,3,3},0,0,true,0);

它的作用: 给定一个向量 v,它会组合和、减法和数字,每当这个组合等于第一个参数时,就会增加一个全局变量 result。例如,count2(6,{1,2,3,3,3},0,0,true,0); 将使result 成为 5。因为有 5 种方法可以将这些数字相加/减去 6,例如:1+2+3+3-31+2-3+3+3 和其他一些。它完美地工作。另外,变量字符串str也没有使用。

出了什么问题? 没什么,但我想看看这些组合是什么。我希望打印的功能是这样的:

1+2+3+3-3
1+2-3+3+3
-1-2+3+3+3
1+2+3-3+3

问题是什么?我想知道如何正确打印使 total 等于 k ​​的操作。 如果你要run this code in ideone,它会打印:YES,这是我的实际结果。但不正确,因为没有 +3 或 +3+3+3+3+3+3+....等总和。

+1+2+3+3-3=6
+3=6
+3-3+3-3-3+3+3=6
+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-1+2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3=6
+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-1+2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3+2+3+3+3-3-3+3-3+3-3-3+3+3-3-3+3-3+3-3+3+3-3-3+3-3+3-3-2+3+3+3=6

正确的结果 可能如下所示:

1+2+3+3-3
1+2+3-3+3
1+2-3+3+3

-1-2+3+3+3

问题已回答!

【问题讨论】:

  • 问题是什么?
  • @NeilKirk 如何打印正确的操作?比如1+2+3+3-3 1+2-3+3+3 -1-2+3+3+3 1+2+3-3+3等等。
  • 通过按值传递向量 d,您正在复制它多次。这是低效的。通过 const 引用传递。您应该返回结果而不是修改全局变量。为什么 mas 和 menos 不是局部变量?
  • @NeilKirk 它应该是低效的。在此之后我们将继续回溯。不用担心内存消耗。 :) mas 和 menos 不是局部变量,因为没有特殊原因,我可以立即更改它,这不会影响我的结果也不会回答问题。 ://
  • 基本上是算法/设计问题。你的 count2 同时做的太多了:1)递归耗尽组合,2)检查结果和 3)打印结果如果我是你,我会先使用一些简单的脚本语言来原型化

标签: c++ string c++11 printing


【解决方案1】:

如果您不介意我稍微更改函数签名,我可以建议以下内容吗?

int recurs = 0;
void count2(int k, std::vector<int> d, int total = 0, std::string temp = "", unsigned short pos = 0)
{
    if(pos == d.size())
    {
        //test total number
        if(total == k)
        {
            std::cout << temp <<"=" << k << std::endl;
            recurs++;
        }
    }
    else
    {
        //test each operator on next number in sequence
        count2(k, d, total + d[pos], temp + ((pos) ? "+":"") + std::to_string(d[pos]), pos + 1);
        count2(k, d, total - d[pos], temp + "-" + std::to_string(d[pos]), pos + 1);
    }
}

条件运算符将从开头删除“+”号。默认值使函数更容易从 main 或任何地方调用。通过将 temp 作为string 发送,可以更轻松地跟踪最终方程,并将其作为全局变量删除。它还消除了对 bool flag 变量的需求。最后,在函数调用中更新total 以消除函数体中的混乱。

【讨论】:

  • 这行得通,但我仍然需要像 123+45 这样的组合。已找到解决方案。
【解决方案2】:

所以最后 count2 看起来像这样:

void count2(int k, std::vector<int> d, int total, int temp, bool flag, unsigned short int pos, std::vector<std::string> s){
    //std::cout << temp << " ";
    if(pos==(d.size())){
        total+=temp;
        if(total==k){
            result++;
            for(unsigned short int i=0;i<d.size();i++){
                std::cout << s[i] << d[i];
            }
            std::cout << "=" << k <<"\n";
        }
        return;
    }
    s[pos]="+";
    count2(k,d,total+temp,+d[pos],true,pos+1,s);
    //put a - sign in pos
    s[pos]="-";
    count2(k,d,total+temp,-d[pos],false,pos+1,s);
    if(pos==0) return;
    //Append digit
    if(flag==true){
        s[pos]="";
        //std::cout << "<0 " << 10*temp-d[pos] << " ";
        count2(k,d,total,(10*temp-d[pos]),true,pos+1,s);
    }
    else{
        s[pos]="";
        //std::cout << ">0" << 10*temp+d[pos] << " ";
        count2(k,d,total,10*temp+d[pos],false,pos+1,s);
    }

}

您可以看到,我使用的是字符串向量,而不是使用字符串变量,这使其适合递归调用。

Give it a try on ideone.com

【讨论】:

    猜你喜欢
    • 2012-07-18
    • 2013-12-25
    • 1970-01-01
    • 2022-01-02
    • 2023-02-18
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多