Print star ('*') diamond in C with nested

2019-02-16 02:27发布

I want to be able to print a diamond like this when the user enters 5 for the diamond. But also will work for any value that is odd and greater than 0.

enter image description here

I have a code that works to make a diamond for user input of 5 but won't work for all odd number inputs..

 half = (size/2)+1;

 for (a=1; a <=  half ; a++) /*top to mid row of diamond*/
   {
     for (b=a; b<half;b++)
       {
     printf(" ");
       }
     for (c= size -2* a; c <=  half; c++)
       {
     printf("*");
       } 
      printf("\n");
   }
 for (a = 1; a < half;a++)
   {
     for (b = a; b>0;b--)
       {
     printf(" ");
       }
     for (c = size-2*a; c >0 ;c--)
       {
     printf("*");
       }
     printf("\n");
   }


  return 0;
}

Any help would be greatly appreciated.Thank you.

Mike

11条回答
唯我独甜
2楼-- · 2019-02-16 03:19

You are probably taking introductory C class right now, and as everyone else I would discourage you from copying, but for reference here is an answer:

To make the answer simple, all you need to know is how many spaces and stars to print.

The sequence is following: [print spaces] [print stars] [print spaces] [print '\n'].
Observe that in the middle row we would need: (0) spaces, (numStars) stars, (0) spaces.
In the row above and below, we would need: (1) space, (numStars - 2) stars, (1) space.
An so on...

This should give you the feeling that to count number of spaces, you need to count the distance from the middle row. Also note that with each row away from the middle, number of stars decreases by 2.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {

    int num, middle, spaceCount, starCount;

    printf("Enter a num:");
    scanf("%d",&num);   

    middle = (num-1)/2;

    for (int i = 0; i < num; i++){

        spaceCount = abs(middle - i);
        starCount = num - 2*abs(middle - i);

        for(int c = 0; c < spaceCount; c++)
            printf(" ");

        for(int c = 0; c < starCount; c++)
            printf("*");

        for(int c = 0; c < spaceCount; c++)
            printf(" ");

        printf("\n");
    }


    return 0;
}

Since we are calculating the distance between the current row and the middle one, we need to know the absolute value. abs function is standard C function to do that.

查看更多
We Are One
3楼-- · 2019-02-16 03:21

Almost certainly homework so here's a clue.

Count the number of spaces before a line and the number of stars in that line. What you're looking for is a relationsip between the line number and those two values.

Then you can use two consecutive for loops, one increasing the star count and the other decreasing it.

Within each of those loops would be two more consecutive loops to print out the required number of spaces followed by the required number of stars followed by a newline character.


If you're still having trouble after reading the above, consider this. For an input of (odd, as you state you enforce in your comments) n, the space count starts at (n - 1) / 2 and the star count at 1. For each subsequent line, the space count reduces by 1 and the star count increases by 2.

That works up until the point where the space count reaches 0, then you turn around and go the other way, making sure you don't print that middle line twice.

Once the star count reaches 0, you're done.

Now you just have to turn that specification into code :-)


Now, since you've indicated in comments that you're interested in making your own solution rather than just being handed code, I feel comfortable giving you something you can check your own solution against. Here's the pseudo-code I would use:

# Input data, check and init counters.

input n
make sure n is odd and greater than 2
set numspaces to (n-1) / 2
set numstars to 1

# Gradually get wider until just before middle line.

while numspaces > 0:
    for i = 1 to numspaces: output " "
    for i = 1 to numstars:  output "*"
    output newline
    subtract 1 from numspaces
    add 2 to numstars

# Gradually get thinner until end.

while numstars > 0:
    for i = 1 to numspaces: output " "
    for i = 1 to numstars:  output "*"
    output newline
    add 1 to numspaces
    subtract 2 from numstars

And, as a final exercise, you can refactor:

    for i = 1 to numspaces: output " "
    for i = 1 to numstars:  output "*"
    output newline

into a separate function, since it's common between the two loops.


And now, since you've got your own code working, here's the Python code I used for proof of concept, included for completeness:

def lineout (sp, st):
    s = ""
    for i in range (sp): s = "%s "%(s)
    for i in range (st): s = "%s*"%(s)
    print s

n = 21
numspaces = (n-1) / 2
numstars = 1

while numspaces > 0:
    lineout (numspaces, numstars)
    numspaces -= 1
    numstars += 2

while numstars > 0:
    lineout (numspaces, numstars)
    numspaces += 1
    numstars -= 2

You could probably write it more succinctly in Python if you used the more modern features but that would rather defeat the purpose of quick understanding and easy translation. Just change n to whatever number you want (odd and greater than two, providing the resultant diamond will fit in your terminal) and enjoy the output :-)

          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
*********************
 *******************
  *****************
   ***************
    *************
     ***********
      *********
       *******
        *****
         ***
          *
查看更多
女痞
4楼-- · 2019-02-16 03:21
#include <iostream>
using namespace std;

int main()
{
int n=0, star=0, space=0, ct2=0, ct3=1;
cin >> n;
ct2=n/2;
for(int ct=0; ct< (n/2); ct++)
{
    for(space; space<ct2; space++)
    {
        cout << " ";
    }
    ct2--;
    space=0;
    for(star; star<ct3; star++)
    {
        cout << "*";
    }
    ct3 += 2;
    star=0;
    cout << endl;
}
ct3=n;
ct2=0;
space=0;
star=0;
for(int ct=0; ct< (n/2); ct++)
{
    for(star; star<ct3; star++)
    {
        cout << "*";
    }
    cout << endl;
    ct3 -= 2;
    star=0;
    ct2++;
    space=0;
    for(space; space<ct2; space++)
    {
        cout << " ";
    }
}
cout << "*" << endl;
return 0;
}
查看更多
你好瞎i
5楼-- · 2019-02-16 03:22

There are two things that occur here:

  1. Indent changes (-1 to "mid", +1 "after")

  2. Star count changes (+2 to "mid", -2 "after")

Now, this could be done with two loops (one for the top to "mid" and one "after"), but the values can also be determined with a little math. Let's explore that :-)

Here are the numbers:

        s(spaces)  x(stars) n(line number)
__X          2        1        0
_XXX         1        3        1
XXXXXX       0        5        2
_XXX         1        3        3
__X          2        1        4

Start by noting that s is symmetrical about the "mid":

  • s = abs(2 - n)

And then that x is related to s (by 2 as noted in deltas above):

  • x = 5 - (s * 2) = 5 - (abs(2 - n) * 2)

Hope that gives some insight!

查看更多
三岁会撩人
6楼-- · 2019-02-16 03:27
 static void Main(string[] args)
        {    //check this out more optimized code hope it will be help full.    
    for (int row=-2;row<=2;row++)
        {
        for (int col=-2;col<=2;col++)
        {
        if (Math.Abs(row)+Math.Abs(col)<=2)
        {
        Console.Write("*");
        }
        else
        {
        Console.Write(" ");
        }
        }
        Console.WriteLine();
        }
            Console.ReadKey();
        }
查看更多
登录 后发表回答