patterncppModerate
To understand what recursion is, you must first understand recursion
Viewed 0 times
youmustrecursionwhatunderstandfirst
Problem
This is the second assignment for my CS2 course:
-
Write a recursive C++ function
produces the output:
-
Write a recursive [C++] function
produces the output:
-
Implement and test a recursive C++ function
height of the pyramid (the number of lines in it). Hint: Each line in
the pyramid should be generated by two calls to writeLine: the first
call generates the spaces and a second call to generate the line of
characters.
The
pyramid of height 3 with the
Please feel free to rip the code apart! In my opinion, I think the
```
#include
#include
#include "lab2functions.h"
char getSanitizedChar()
{
// absorb newline character (if existant) from previous input
if('\n' == std::cin.peek()) std::cin.ignore();
return std::tolower(std::cin.get());
}
int main()
{
char type = '*';
char shape = 'l';
int rows = 0;
int cols = 0;
do
{
std::cout > shape;
switch(shape)
{
case 'l':
std::cout > cols;
std::cout > rows;
std::cout > cols;
std::cout > rows;
std::cout << "Enter character to build with (*): ";
type = getSanitizedChar();
writePyramid(('\n' == type ? '*' : type), rows);
break;
default:
std::cout << "Invalid option";
break;
}
std::cout << "\nRun a calculation again (y/N
-
Write a recursive C++ function
writeLine() that writes a character repeatedly to form a line of n characters. For example:writeLine('*', 5)produces the output:
*****-
Write a recursive [C++] function
writeBlock() that uses writeLine to write m lines of n characters each. For example,writeBlock('*', 5, 3)produces the output:
*****
*****
*****-
Implement and test a recursive C++ function
writePyramid(). The function should take in a character to build a pyramid with and theheight of the pyramid (the number of lines in it). Hint: Each line in
the pyramid should be generated by two calls to writeLine: the first
call generates the spaces and a second call to generate the line of
characters.
The
␣ in the output below represents a space character. This output is generated when the function is asked to generate apyramid of height 3 with the
* character.␣␣*
␣***
*****Please feel free to rip the code apart! In my opinion, I think the
switch in main() could be DRYed up a bit, but I wasn't sure how.lab2.cpp:```
#include
#include
#include "lab2functions.h"
char getSanitizedChar()
{
// absorb newline character (if existant) from previous input
if('\n' == std::cin.peek()) std::cin.ignore();
return std::tolower(std::cin.get());
}
int main()
{
char type = '*';
char shape = 'l';
int rows = 0;
int cols = 0;
do
{
std::cout > shape;
switch(shape)
{
case 'l':
std::cout > cols;
std::cout > rows;
std::cout > cols;
std::cout > rows;
std::cout << "Enter character to build with (*): ";
type = getSanitizedChar();
writePyramid(('\n' == type ? '*' : type), rows);
break;
default:
std::cout << "Invalid option";
break;
}
std::cout << "\nRun a calculation again (y/N
Solution
Usually we write recursive functions with the exit condition all by itself:
I would normally write this as:
No real reason apart from tradition I suppose. But it does show tail recursion more clearly. The compiler can easily optimize tail recursion into a loop for you. But it also makes it obvious to the human eye where tail recursion is.
A static member of a recursive function!!!
That's a bit strange. You normally pass all values as parameters between iterations. If you need a defaulting starting value then you can either use a wrapper function that calls your recursive function and provides the initial value. Or have a parameter that defaults to the start value but internally you increment it (I choose the second here).
I know that
Going back to your wrapper code:
All the switch statements contain the same bit of code:
Keep it DRY. Either move this into a separate function (called from each case). Or move it to before the switch intirally.
void writeLine(const char c, const int8_t num)
{
if (num > 0)
{
std::cout << c;
writeLine(c, num - 1);
}
}I would normally write this as:
void writeLine(const char c, const int8_t num)
{
if (num <= 0)
{
return;
}
std::cout << c;
writeLine(c, num - 1);
}No real reason apart from tradition I suppose. But it does show tail recursion more clearly. The compiler can easily optimize tail recursion into a loop for you. But it also makes it obvious to the human eye where tail recursion is.
A static member of a recursive function!!!
void writePyramid(const char c, const int8_t h)
{
static int count;
count++;That's a bit strange. You normally pass all values as parameters between iterations. If you need a defaulting starting value then you can either use a wrapper function that calls your recursive function and provides the initial value. Or have a parameter that defaults to the start value but internally you increment it (I choose the second here).
void writePyramid(const char c, const int8_t h, int count = 0)
{
if (h <= 0)
{
return;
}
writeLine(' ', (2 * h - 1) / 2);
writeLine(c, (2 * count - 1));
std::endl(std::cout);
writePyramid(c, h - 1, count + 1);
}I know that
Static storage duration objects are zero initialized. But how many of your peers know this. It would have been nice to give them a hint.static int count = 0;Going back to your wrapper code:
All the switch statements contain the same bit of code:
std::cout > rows;
std::cout > cols;
std::cout << "Enter character to build with (*): ";
type = getSanitizedChar();Keep it DRY. Either move this into a separate function (called from each case). Or move it to before the switch intirally.
Code Snippets
void writeLine(const char c, const int8_t num)
{
if (num > 0)
{
std::cout << c;
writeLine(c, num - 1);
}
}void writeLine(const char c, const int8_t num)
{
if (num <= 0)
{
return;
}
std::cout << c;
writeLine(c, num - 1);
}void writePyramid(const char c, const int8_t h)
{
static int count;
count++;void writePyramid(const char c, const int8_t h, int count = 0)
{
if (h <= 0)
{
return;
}
writeLine(' ', (2 * h - 1) / 2);
writeLine(c, (2 * count - 1));
std::endl(std::cout);
writePyramid(c, h - 1, count + 1);
}static int count = 0;Context
StackExchange Code Review Q#79814, answer score: 10
Revisions (0)
No revisions yet.