Still though, I didn't even think about being able to add or subtract from the parameter inside the recursive call yet(I just started on recursion, and it's hard to wrap my mind around how they seem to almost work from both ends and meet in the middle), so that simultaneously opens up new possibilities for me and sets me back about 2 days of understanding lol.
I try to avoid the last (empty) line but fail. How may I filter it in main()? IMO four lines would be enough for printTriangle( 4 ).
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include <iostream>
#include <string>
usingnamespace std;
string printTriangle( int n )
{
return n ? string( n, '*' ) + '\n' + printTriangle( n - 1) : "\0";
}
int main()
{
cout << printTriangle( 4 );
cout << "<<< End of last line is here.";
}
Edit:
Reult from the code above is
****
***
**
*
<<< End of last line is here.
Solved my requirement (remove empty line) like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include <iostream>
#include <string>
usingnamespace std;
string printTriangle( int n )
{
return (n-1) ? string( n, '*' ) + '\n' + printTriangle( n - 1) : "*";
}
int main()
{
cout << printTriangle( 4 );
cout << "<<< End of last line is here.";
}
Assuming that we do not want pass objects by reference to recursive functions,
avoiding creation of temporary strings, and moving rather than copying strings may be more (machine) efficient.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <string>
void printAst( std::string ast ) {
if( !ast.empty() ) {
std::cout << ast << '\n' ;
ast.pop_back() ; // knock off the last character O(1)
printAst( std::move(ast) ) ; // and avoid a deep copy
}
}
int main() {
printAst( "********************************" );
}
You could just do a failsafe check after line 6 in lastchance's code.
Something similar was my first idea too, prevent the last call to printTriangle(). Alas it would disturb the elegance of the {(test)? (if true) : (if not)} construct.
Will every stackoverflow check be an if statement? I've never seen anyone use a while for it.
Consider a tree. Each node has a list of children. (Leaf nodes have empty list.)
1 2 3 4 5 6 7
walk( Node* root ) {
// do something with root
for ( auto child : root->children ) {
walk( child );
}
// do something with root
}
Yes, you could have if ( root->children.empty() ) there too, but if you do iterate children (rather than recurse) and it does suffice to "not recurse" on leaf, then you might see a loop.