tags:

views:

810

answers:

6

This is a homework question I got for my programming course at school, and I'm kind of lost, so please help. Here is the question:

Write an application program that prints a diamond of asterisks (*) on the screen. The number of lines in the diamond is given by the user. As an example, if the user requested a diamond with 7 lines, the following would be displayed.

Here is what I have so far:

{
  int nlines;
  int nsp;
  cout << "enter the number of lines (must be more then one)" << endl;
  cin >> nlines;
  while((nlines)<=0)
  {
    cout << "enter the number of lines (must be more then one)" << endl;
    cin >> nlines;
  }
  nsp=(nlines - 1)/2;
  for(int currspace = 1; currspace <= nsp; currspace++)
  {
    cout << " ";
  }
  cout << "*" << endl;
  for( int currentline = 0; currentline < nlines; currentline++)
  {
    for( int currentaster = 0; currentaster <= currentline; currentaster++)
      cout << "*";
    cout << endl;
  }
  return 0;
+12  A: 

I won't try to give a complete answer since it's homework, but my immediate advice would be to try to break the task down into some sub-tasks, each of which is somewhat simpler. For example, I'd start with a small function that did nothing but print out one line of asterisks of a specified length with a specified justification. From the looks of things, you can probably handle that pretty easily, and one you have it, the rest is quite a bit more straightforward.

Jerry Coffin
I'd factor out repeat-this-character-this-many-times - the one line of asterisks can re-use that twice (the indent and the asterisks).
Steve314
Normally I'd agree -- but (hint, hint) if he looks through the constructors for std::string and the manipulators for std::ostream, he'll quickly realize that for this task, it's easiest to do the two differently from each other...
Jerry Coffin
Extra hint - a recursive function might impress. Draw an x-asterisks line, if less than half-way recurse for x+2, then draw another x-asterisks line.
Steve314
@Jerry - different guesses about order-of-learning? I vaguely remember once doing a similar program in Pascal, before doing anything with strings other than print them. Mind you, this was in the days of Turbo Pascal 3.
Steve314
I'm not sure what you're asking about different orders of learning here...
Jerry Coffin
@Jerry - not really a question - just thinking that maybe you would expect strings to be taught a bit earlier than I would. Of course I also suggested recursion, so I'm not necessarily sane in this.
Steve314
+5  A: 

Perhaps a good start would be for you to write a function that writes n spaces, and m stars on the screen.

theycallmemorty
+5  A: 

As it's homework, I'll just recommend some steps you might want to take, and let you have the fun of actually writing it :-)

So to print a diamond, I assume it'll be something like this (example with 5 lines - the number of lines must be odd)

  *
 ***
*****
 ***
  *

I marked the positions of the characters. So what you'll need to do is work out how many spaces you need to print, and then how many asterisks. After each line, work out how many spaces you have to add/subtract based on the current line number, and then work out how many asterists you have to add/subtract. Some steps I'd recommend:

  1. Write a function that calculates the number of spaces to print, given the total number of lines and the current line number
  2. Write a similar function for number of asterisks
  3. Use these two functions to print out the diamond, line by line.
Smashery
+2  A: 

Other people are suggesting that you design it "bottom up", by developing useful subroutines.

Another approach is to design a program "top-down": by writing the code in main first, assuming that any/all useful subroutines which would help to implement the solution already exist: because doing this will let you decide what subroutines you want to have.

For example:

int main()
{
  int nLinesTotal = getNumberOfLinesFromUser();
  int nLinesTopHalf = getHalfOf(nLinesTotal);
  //caution: using 1-based not 0-based index here
  for (int i = 1; i <= nLinesTopHalf; ++i)
  {
    int nAsterisksOnThisLine = calculateAsterisks(i);
    //following function takes nLinesTotal as a parameter because
    //that's necessary to calculate how wide the diamon is and
    //therefore how much leading whitespace there is on each line
    printAsterisks(nLinesTotal, nAsterisksOnThisLine);
  }
  ... etc for the middle line
  ... and for the bottom half of the diamond
}

Doing this shows that it would be useful to have the subroutines like the following:

  • getNumberOfLinesFromUser
  • getHalfOf
  • calculateAsterisks
  • printAsterisks
ChrisW
+3  A: 

Here's how I'd do it. Examine some sample diamonds (5, 7 and 9 lines):

                         *
             *          ***
   *        ***        *****
  ***      *****      *******
 *****    *******    *********
  ***      *****      *******
   *        ***        *****
             *          ***
                         *

The first line consists on some spaces and some stars. How many? Number of stars is always one, number of spaces depends on the number of lines desired:

Number of lines  |  Initial space count
-----------------+---------------------
       1         |            0
       2         |            0
       3         |            1
       4         |            1
       5         |            2
       6         |            2
       7         |            3
       8         |            3

So the initial number of spaces is (#lines - 1) / 2, rounded down.

The other thing you'll notice is that on each subsequent line, the number of spaces reduces by one and the number of stars increases by two.

That's up until the point where the number of spaces is zero, then you start increasing spaces by one and decreasing stars by two until the number of stars is once again one.

The only other special case is an even number of lines where you should duplicate the middle line.

Looking at your code, you're very close, you just have to adjust where the loop statements are in relation to what's being printed. In other words, the outer loop is for lines, then an inner loop for spaces followed by another inner loop for stars.

I wrote a test program in Python (see below) but you really shouldn't have to understand Python syntax (that program's a lot bigger than I originally thought it would be) to get some use from this answer so here's some simplified pseudo-code. You should always sit down and think out the problem before you start writing code. This will help you develop the skills that will do you well in the future.

Main:
    Get numlines from user, check that greater than 0.
    Set numstars to 1.
    Set numspaces to int((numlines-1)/2)
    call Output (numspaces,numstars)
    while numspaces > 0:
        numspaces = numspaces - 1
        numstars = numstars + 2
        call Output (numspaces,numstars)
    if numlines is even:
        call Output (numspaces,numstars)
    while numstars > 0:
        numspaces = numspaces + 1
        numstars = numstars - 2
        call Output (numspaces,numstars)
    end.

Output(spaces,stars):
    for i = 1 to spaces:
        print " "
    for i = 1 to stars:
        print "*"
    print end-of-line
    return

Finally, here's the Python code I used to test the pseudo-code (not really giving you the code since you need C++):

import sys

# Construct line based on number of spaces and stars.
def outLine (spc,str):
    # Start with empty line.
    line = ""

    # Add spaces.
    for i in range(0,spc):
        line = "%s "%(line)

    # Add stars.
    for i in range(0,str):
        line = "%s*"%(line)

    #Output line.
    print line

# Get number of lines from user and check.

numlines = input ("Enter number of lines: ")
if numlines < 1:
    print "Must be greater than zero"
    sys.exit(1);

# Calculate initial space and star count.
numspaces = int ((numlines-1)/2)
numstars = 1

# Output initial line.
outLine (numspaces,numstars)

# Output subsequent lines until middle reached.
while numspaces > 0:
    numspaces = numspaces - 1
    numstars = numstars + 2
    outLine (numspaces,numstars)

# Repeat middle if even number of lines desired.
if numlines % 2 == 0:
    outLine (numspaces,numstars)

# Output the bottom half of the diamond.
while numstars > 0:
    numspaces = numspaces + 1
    numstars = numstars - 2
    outLine (numspaces,numstars)

and here's an example run:

Enter number of lines: 15
       *
      ***
     *****
    *******
   *********
  ***********
 *************
***************
 *************
  ***********
   *********
    *******
     *****
      ***
       *
paxdiablo
A: 
Vadakkumpadath
There are more efficient algorithms. You have to work on it yourself.
Vadakkumpadath
Complete answers on homework questions earn negative points. Even if you recommend the OP comes up with a better answer, leaving a valid answer up there still opens up the opportunity to cheat with (or otherwise be excessively "inspired by") the answer.
Coding With Style
But it would've been great if it stopped before the actual code. Good example with the coords.
Per Wiklander