Don't think in "code" first, try to describe the problem in your own words first.
Imagine, you had to explain the problem to your grand mother. How would you explain?
Maybe, you start at the basics:
- I have to write a computer program that prints on a computer display some N rows and columns that show some triangle of the form
....*
...**
..***
.****
*****
- the number of rows and columns (N) may vary for different squares (in the example, N is set to 5)
- since computer displays are row-wise filled (like writing text on type writer), the program writes the image row by row, starting at the top
- I use a dot (.) to move forward one character in the line and an asteriks (*) to draw a fraction of the triangle
- the lines are printed as follows:
- the first line prints 4 dots and 1 asteriks
- the second line prints 3 dots and 2 asteriks
- ...
- the second last line prints 1 dot and 4 asteriks
- the last line prints 0 dots and 5 asteriks
- trying to replace the number 5 by N, this can be described as
- line 1: N-1 dots, 1 asteriks
- line 2: N-2 dots, 2 asteriks
- ...
- line N-1: 1 dot, N-1 asteriks
- line N: 0 dots, N asteriks
Now you are ready to translate into something like code, called
pseudo code (since it is not a particular language like C++, you have the freedom to write in your
native language):
1. get size of the image which is the number of rows to print and store the value in N
2. print N lines, one line after the other, in the following way (line number 1...N):
1. print so many dots: N minus linenumber
(e.g. line 1: N-1, which results for N = 5: 5-1 = 4)
2. print so many asteriks: linenumber (e.g. line 1: 1)
From this pseudo code, you now have to find a match to your computer language, e.g. C++.
- get size of image:
cout <<"prompt to the user..."; int n; cin >>n;
- print N lines:
for(int row = 1; row <= n; ++row) { PrintLineOneBased(n, row); }
or int row = 1; while(row <= n) { PrintLineOneBased(n, row); row++; }
or be using the more commonly used zero-based counting
for(int row = 0; row < n; ++row) { PrintLineZeroBased(n, row); }
or the equivalent while loop
int row = 0; while(row < n) { PrintLineZeroBased(n, row); row++; }
- PrintLineZeroBased(int n, int line):
PrintSpacesZeroBased(n, line); PrintAsteriksZeroBased(n, line);
- PrintSpacesZeroBased(int n, int line):
/* print n-(line+1) dots */
for(int col = 0; col < n-(line+1); col++) cout <<'.';
- PrintAsteriksZeroBased(int n, int line):
/* print (line+1) asteriks */
for(int col = 0; col < (line+1); col++) cout <<'*';
Admitteldy, the step from one-based to zero based is mean ;-)
You could have defined the OneBased methods likewise and carefully set the loop init and conditions.
Or, since you know that many programming languages are zero based by nature, you coukd have stated the pseudo code already in such a manner, e.g.
1. get size of the image which is the number of rows to print and store the value in N
2. print N lines, one line after the other, in the following way (line number 0...(N-1)):
1. print so many dots: N minus (linenumber plus 1)
(e.g. line 0: N-1, which results for N = 5: 5-(0+1) = 4)
2. print so many asteriks: linenumber plus 1 (e.g. line 0: (0+1))
Key items for designing and implementing:
1) state the problem in your words
2) write pseudo code
3) divide into functions
4) carefully check the loop conditions (init, execute-while condition, increment)
Cheers
Andi
PS: This is a general approach: for tiny problems like this as well as for far more complex ones. This is called: "top-down approach" - you start at the top-most problem and divide it into smaller ones.
PPS: If you have to understand what your initial code does, do a walk-through: list all variables on a piece of paper and go through step-by-step and write manually down what is does (variable values, output). Add comments to the code to tell what the lines do, e.g.
/* loop over all lines 0..(N-1) */
, etc. You will see that that code is broken and you have to decide if you want to fix the broken code or if you implement your own from scratch.
This is BTW a daily situation of every software developer: "fix it or dump it". What drives that decision? Commercial and quality considerations (as well as if I understand the code and the domain well enough to either fix or re-write): can I afford to re-write the code, and can I test the code to give a better confidence level of what I do? You are responsible for the outcome of that work (during the studies as well as professional), so it's also your reputation that depends on that.