Reputation: 3
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?
Upvotes: 0
Views: 86
Reputation: 5566
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
Upvotes: 0
Reputation: 5877
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.
Upvotes: 2