简体   繁体   中英

Not understanding return in this recursive function (C++)

    string stringtest(const string& s, int size, int index, string res){

       if(index == size){return res;}

        char c = s.at(index);

        if(isalpha(c)){ res+= c ; }

      **return**  stringtest(s,size,index+1,res);

    }

    string stringtest(const string& s){
        int size = s.size();
        string r = "";

     return stringtest(s,size,0,r);

    }

    int main(){
      cout <<   stringtest("1a2bc3def") << endl;
        return 0;
}

Hello. This is a piece of code I wrote to learn recursion.

What i do not understand is the functioning of the return inside the helper function stringtest(string,size,index,result) - I just want to return the result at the end, why do I return the function call each time?

EDIT

So.. is it because when I return res it returns back to the calling function and since I never return those function calls then it never gets back to where I call stringtest("1a2...") in the main?

The key thing to understand is that return followed by some expression does not immediately return some value. It computes the expression (which represents the recursive call) and then returns the value that the computed expression evaluates to. You are missing the intermediate computation that is done before some value is returned.

Within this intermediate computation, because of the recursion, it will launch another intermediate computations whose result it will return once computed . These intermediate computations keep being launched until the base case of the recursion is reached.

Without the return statement at the end, because the function has a non-void return type, you encounter undefined behavior.

What i do not understand is the functioning of the return inside the helper function stringtest(string,size,index,result) - I just want to return the result at the end, why do I return the function call each time?

It is always allowed (and relatively easy) to add a pair of removable cout's to display a 'graphic' illustrating the recurse / decurse action. Each function call (of stringtest()) returns to the line after the call.

I added a single parameter to track the recursion level, "size_t rLvl". Note that in the decursion the rLvl is restored. The rLvl is used to displace the current value, thus increasing rLvl during recurse pushes the intermediate values of 'res' to the right, and the restore of rLvl during decurse restores the alignment of the decurse report with corresponding recurse report.

#include <iostream>
using std::cout, std::endl; // c++17

#include <iomanip>
using std::setw;

#include <string>
using std::string, std::to_string;


string stringtest(size_t rLvl, // recurse lvl
                  const string& s, size_t size, size_t index, string res)
{
   int w = static_cast<int>(2*rLvl);
   if(index == size)  // recursion termination clause
   {
      int sz = static_cast<int>(s.size());
      cout << "\n  " << setw(3) << rLvl
           << "  " << s << setw(w-sz-4) << " "
           << res << "   <<<<< end-of-recursion";
      return res;
   }

   char c = s.at(index);

   if(isalpha(c)) { res += c; }  // append c when it is alpha

   // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

   cout << "\n  " << setw(3) << rLvl                 // recurse report
        << setw(w) << " "
        << setw(4) << res << " ";

   string temp = stringtest(rLvl+1, // recurse lvl   // recursion invocation
                            s, size, index+1, res);

   cout << "\n  " << setw(3) << rLvl                 // decurse report
        << setw(w) << " "
        << setw(4) //<< "-"
        << res << '_';  //<< ")";

    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   return temp;
}

string stringtest(const string& s)
{
   size_t size = s.size();
   string r = "";
   return stringtest(1, s, size, 0, r);
}

int main()
{
   string res = stringtest("1a2bc3def");
   cout << "\n\n  result: " <<  res  << endl;
   return 0;
}

Output:

    1       
    2       a 
    3         a 
    4          ab 
    5           abc 
    6             abc 
    7              abcd 
    8                abcde 
    9                  abcdef 
   10  1a2bc3def       abcdef   <<<<< end-of-recursion
    9                  abcdef_
    8                abcde_
    7              abcd_
    6             abc_
    5           abc_
    4          ab_
    3         a_
    2       a_
    1      _

  result: abcdef

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM