My problem is that I don't understand nested loops well enough to answer this problem. I'm supposed to right-align a stack that I've made on a left alignment using nested for loops, but I can't quite figure out the conditions on the two inner ones.
Correct answer:
Height = 8
.......#
......##
.....###
....####
...#####
..######
.#######
########
My answer:
Height = 8
.......#
.......#......#
.......#......#.....#
.......#......#.....#....#
.......#......#.....#....#...#
.......#......#.....#....#...#..#
.......#......#.....#....#...#..#.#
.......#......#.....#....#...#..#.##
I've played around with it, took it seriously and nothing. I did (k = 7, k > j, k--), (k = 0, k < n-1, k++), k < j+7, I drew tables and i know that the height is pretty much the same as the value of the spaces but inverted on each line. I also know that the value of the hashes and the spaces should be equal to the height input by user.
It's supposed to take in a value from user, but I've worked on it on a separate file with the value n being the height to simplify and work on it without the rest of the program.
#include <stdio.h>
int main(void) {
int n = 8;
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
for(int k = 7; k > j; k--) {
printf(".");
}
printf("#");
}
printf("\n");
}
}
It's actually pretty simple. Write a table with each line and how many spaces and '#'
you need to print:
n == 8
| output | line | num_spaces | num_signs |
| -------- | ---- | ---------- | --------- |
| .......# | 1 | 7 | 1 |
| ......## | 2 | 6 | 2 |
| .....### | 3 | 5 | 3 |
| ....#### | 4 | 4 | 4 |
| ...##### | 5 | 3 | 5 |
| ..###### | 6 | 2 | 6 |
| .####### | 7 | 1 | 7 |
| ######## | 8 | 0 | 8 |
For line
you can start from 0
or from 1
or from n
and go backwards. Pick something that is the easiest. You will see that starting from 1
is the simplest in your example.
Now for each line
we need to determine how many num_spaces
and num_signs
we print. They should depend on line
and on n
.
For num_spaces
it's n - line
and for num_signs
it's line
So the code should look like this:
// for each line
for (int line = 1; line <= n; ++line)
{
// print n - line spaces
// print line # characters
// print \n
}
With loops the code will look like this:
// for each line
for (int line = 1; line <= n; ++line)
{
// print n - line spaces
for (int i = 0; i < n -line; ++i)
std::cout << ' ';
// print line # characters
for (int i = 0; i < line; ++i)
std::cout << '#';
std::cout << '\n';
}
std::cout.flush();
But that's actually not recommended. You can get rid of those inner loops. One good and easy way is to use strings:
// for each line
for (int line = 1; line <= n; ++line)
{
// print n - line spaces
std::cout << std::string(n - line, ' ');
// print line # characters
std::cout << std::string(line, '#');
std::cout << '\n';
}
std::cout.flush();
And you can go even one step further:
// for each line
for (int line = 1; line <= n; ++line)
{
// print n - line spaces and line # characters
std::cout << std::string(n - line, ' ') << std::string(line, '#') << '\n';
}
std::cout.flush();
I'm supposed to right-align a stack that I've made on a left alignment using nested for loops, but I can't quite figure out the conditions on the two inner ones.
I think your word problem can be made more solvable by using somewhat more meaningful variable and function names. The words might help guide how you think about your effort, and certainly reveal more to your readers. Single char symbols have little meaning.
On the other hand, there do exist several efforts where single char names and vars are more than tolerated, but actually expected ... for example, matrix math (perhaps for computer generated graphics) often use indexes named simply x,y,z and perhaps t, and would cause no issues for the careful author.
I have prepared 4 examples for you, which I have labeled 'X', 'a', 'b', and 'c'. Each example is packaged as a functor (for my convenience).
To begin, functors 'X' and 'a' are the "same", such that I would expect the compiler to gen very similar code. You might not be able to confirm that with a single glance. The difference is that Example 'X' has single char vars and function names. And example 'a' has more than 1 letter symbols, but not full 'properly spelled' words, either.
Functor Descriptions:
'X' iterative, returns int 0, cout of step pattern
vars: n, i, j, k
functions: x(), p()
'a' iterative, returns int 0, cout of step pattern
vars: maxPtrnHgtWdth, step
function: exec(), dotPndLine()
goal: Perhaps these longer symbol names might help guide development effort, or at least make it easier reading.
class T934X_t // 'X'
{
public:
int operator()(int64_t n) { return x(n); }
private:
int x(int64_t n)
{
cout << "\n\n\n int T934X_t()(int64_t) -->"
<< " int x (int64_t) (" << n
<< ")\n iterative, return 0, cout step pattern, vars: n, i, j, k ";
for (uint i = 0; i < n; ++i) {
p(n, i+1);
}
return 0;
}
// 1..n
void p (int64_t n, uint j)
{
cout << "\n ";
for (uint k = 0; k < (n - j); ++k) { cout << '.'; }
for (uint k = 0; k < j; ++k) { cout << '#'; }
cout << ' ' << flush;
}
}; // class T934X_t
class T934a_t // 'a'
{
public:
int operator()(int64_t maxPtrnHgtWdth) { return exec(maxPtrnHgtWdth); }
private:
int exec (int64_t maxPtrnHgtWdth)
{
cout << "\n\n\n int T934a_t()(int64_t) -->"
<< " int exec (int64_t) (" << maxPtrnHgtWdth
<< ")\n iterative, return 0, cout 'step' pattern ";
for (uint step = 0; step < maxPtrnHgtWdth; ++step) {
dotPndLine (maxPtrnHgtWdth, step+1);
}
return 0; // meaningless
}
// 1..8
void dotPndLine (int64_t maxPtrnHgtWdth, uint step)
{
cout << "\n "; // 8 - 1..8
for (uint dotCt = 0; dotCt < (maxPtrnHgtWdth - step); ++dotCt) { cout << '.'; }
for (uint pndCt = 0; pndCt < step; ++pndCt) { cout << '#'; }
cout << " " << flush;
}
}; // class T934a_t
More Functor Descriptions: (two more to consider)
'b': iterative, returns a string containing the step pattern
Similar to 'a', but uses stringstream instead of 'on-the-fly-cout'. This is a simple kind of 'delayed' output technique. I use this to support the sharing (by multiple threads) of a single output stream (such as cout).
'c': tail recursive , return a string which contains step pattern
I have included because I am a fan of recursion, and thought these relatively simple examples of recursive looping might be helpful for someone new to recursion.
class T934b_t // 'b'
{
stringstream ss;
int64_t maxPtrnHgtWdth;
public:
string operator()(int64_t a_max)
{
maxPtrnHgtWdth = a_max;
exec ();
return ss.str();
}
private:
void exec ()
{
ss << "\n\n\n string T934b_t()(int64_t) -->"
<< " void exec (int64_t) (" << maxPtrnHgtWdth
<< ")\n iterative, return string which contains step pattern";
for (int64_t step = 0; step < maxPtrnHgtWdth; ++step) // step 0..7
{
dotPndLine (step+1); // build each line with dots and pound signs
}
}
// 1..8
void dotPndLine (int64_t step)
{
ss << "\n "; // 8 - 1..8
for (int64_t dotCt = 0; dotCt < (maxPtrnHgtWdth - step); ++dotCt) { ss << '.'; } // dot
for (int64_t pndCt = 0; pndCt < step; ++pndCt) { ss << '#'; } // pnd
ss << " ";
}
}; // class T934b_t
class T934c_t // 'c'
{
stringstream ss;
int64_t maxPtrnHgtWdth;
public:
string operator()(int64_t max)
{
maxPtrnHgtWdth = max;
exec();
return ss.str();
}
private:
void exec ()
{
ss << "\n\n\n string T934c_t()(int64_t): -->"
<< " void exec (int64_t) (" << maxPtrnHgtWdth
<< ")\n tail recursive, return string which contains step pattern, ";
execR (maxPtrnHgtWdth); // entry to recursive code
}
// 8..1
void execR (int64_t step)
{
if (0 >= step) return; // recursion termination
dotPndLine (step-1); // build each line with dots and pound signs
execR (step-1); // tail recursion
}
// 7..0
void dotPndLine (int64_t step)
{
ss << "\n ";
dotR (step); // 7..0 dots
pndR (maxPtrnHgtWdth-step); // 1..8 pound sign
ss << ' ';
}
// 7..0
void dotR (int64_t dotCt) {
if (0 >= dotCt) return; // recursion termination
ss << '.';
dotR (dotCt-1); // tail recursion
}
// 1..8
void pndR (int64_t pndCt) {
if (0 >= pndCt) return; // recursion termination
ss << '#';
pndR (pndCt-1); // tail recursion
}
}; // class T934c_t
I build these 4 functors (and main and some simple code to activate), all in a single file.
#include <iostream>
using std::cout, std::cerr, std::endl, std::flush;
#include <string>
using std::string, std::stol;
#include <sstream>
using std::stringstream;
#include <cassert>
class T934X_t // 'X'
{
// ... move previous code here
}
class T934a_t // 'a'
{
// ... move previous code here
}
class T934b_t // 'b'
{
// ... move previous code here
}
class T934c_t // 'c'
{
// ... move previous code here
}
// main invokes the functor
class T934_t
{
public:
int operator()(int argc, char* argv[])
{
if (argc < 2) {
cerr << "\n expecting height/width limit: uint > 2\n" << endl;
return -1;
}
if(false) // enable for system info
{
string s;
s.reserve(26000000);
cout << "\n\n T934_t() (implementation details)" // ubuntu, g++7
<< "\n sizeof(long int): " << sizeof(long int) // 8 bytes
<< "\n sizeof(int64_t) : " << sizeof(int64_t) // 8 bytes
<< "\n string.size() : " << s.size() // 0 elements
<< " sizeof(string) : " << sizeof(string); // 32 bytes
for (int i=0; i<1000000; ++i)
for (char kar='a'; kar<='z'; ++kar)
s += kar;
cout << "\n string.size() : " << s.size() // 260000 elements
<< " sizeof(string) : " << sizeof(string) // 32 bytes
<< endl;
} // string s destructs here
// user selected stair step max Pattern Height Width
int64_t maxPtrnHgtWdth = stol(argv[1]);
if (maxPtrnHgtWdth < 2) { maxPtrnHgtWdth = 8; }
else if (maxPtrnHgtWdth > 80) { maxPtrnHgtWdth = 79; } // arbitrary limit
return exec (maxPtrnHgtWdth);
}
private:
// this functor exec() invokes 'X', 'a', 'b', and 'c'
int exec (int64_t maxPtrnHgtWdth)
{
int retVal = 0;
// iterative, return 0 ignored, cout step pattern,
// vars: n, i, j, k, functions x(), p()
(void)T934X_t()(maxPtrnHgtWdth);
// iterative, return 0 ignored, cout 'step' pattern,
// functions exec(), dotPndLine()
(void)T934a_t()(maxPtrnHgtWdth);
// iterative, return string which contains step pattern
cout << T934b_t()(maxPtrnHgtWdth) << flush;
// tail recursive, returns string which contains step pattern
cout << T934c_t()(maxPtrnHgtWdth) << flush;
cout << "\n\n\n T934_t::exec()"
<< " (__cplusplus: " << __cplusplus << ")"
<< std::endl;
return retVal;
}
}; // class T934_t
int main(int argc, char* argv[]) { return T934_t()(argc, argv); }
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.