【问题标题】:Print star ('*') diamond in C with nested loops?用嵌套循环在C中打印星形('*')菱形?
【发布时间】:2012-05-04 21:58:26
【问题描述】:

当用户为钻石输入 5 时,我希望能够像这样打印钻石。但也适用于任何奇数且大于 0 的值。

我有一个代码可以为用户输入 5 制作菱形,但不适用于所有奇数输入..

 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;
}

任何帮助将不胜感激。谢谢。

迈克

【问题讨论】:

  • 你不需要嵌套循环,两个循环怎么样,一个递增,一个递减,尝试一下并报告你的尝试。
  • 谷歌上到处都是结果和例子(“C print diamond”),到目前为止你尝试过什么?
  • 试着问自己以下问题:第一行需要打印多少个空格和星号?与前一行相比,每行需要多少个空格和星号?在某些时候,您需要打印更多的空格和更少的星号:什么时候?
  • 重新标记为作业。不想冒犯,但如果你坐下来思考 5 分钟,这很简单。
  • @Dogbert,这是一个相当危险的假设。我敢肯定,大多数病理学护士都认为抽血“非常简单”,但这不是我会尝试的事情。这里的人们在各个领域的技能水平大相径庭。

标签: c loops for-loop nested


【解决方案1】:

这里发生了两件事:

  1. 缩进变化(-1 到“中”,+1“后”)

  2. 星数变化(+2 到“中”,-2“后”)

现在,这可以通过两个循环来完成(一个用于顶部到“中间”,一个用于“之后”),但也可以通过一些数学运算来确定这些值。让我们探索那个 :-)

这里是数字:

 s(空格) x(星号) n(行号)
__X 2 1 0
_XXX 1 3 1
XXXXXX 0 5 2
_XXX 1 3 3
__X 2 1 4

首先要注意s 是关于“中间”对称的:

  • s = abs(2 - n)

然后 xs 相关(如上面的增量中所述为 2):

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

希望能提供一些见解!

【讨论】:

    【解决方案2】:

    几乎可以肯定是作业,所以这里有一个线索。

    计算一行前的空格数和该行中的星号。您正在寻找的是行号与这两个值之间的关系。

    然后您可以使用两个连续的for 循环,一个增加星数,另一个减少它。

    Within 每个循环将是两个更多连续循环,以打印出所需数量的空格,后跟所需数量的星号,然后是换行符。


    如果您在阅读以上内容后仍然遇到问题,请考虑这一点。对于(奇数,正如您在 cmets 中强制执行的)n 的输入,空间计数从 (n - 1) / 2 开始,星数从 1 开始。对于后续的每一行,空格数减少1,星数增加2

    直到空间计数达到0,然后你转身走另一条路,确保你没有打印两次中间线。

    一旦星数达到0,您就完成了。

    现在您只需将该规范转换为代码 :-)


    现在,由于您在 cmets 中表示您有兴趣制定自己的解决方案,而不仅仅是交给代码,因此我很乐意为您提供一些您可以检查自己的解决方案的东西。这是我将使用的伪代码:

    # 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
    

    并且,作为最后的练习,您可以重构:

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

    放到一个单独的函数中,因为它在两个循环之间是通用的。


    现在,既然您已经拥有自己的代码,下面是我用于概念验证的 Python 代码,包括在内:

    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
    

    如果您使用更现代的功能,您可能可以在 Python 中更简洁地编写它,但这会破坏快速理解和易于翻译的目的。只需将n 更改为您想要的任何数字(奇数且大于 2,前提是生成的钻石适合您的终端)并享受输出:-)

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

    【讨论】:

    • 我理解整个概念,即当有 0 个空格时,在中间点之后空格减少,星星增加,反之亦然。我将使用哪种 if/else 语句来控制是否打印 * 或空格?抱歉,我只是一个初学者,试图清楚地理解和学习这一点。
    • @Mike,您不使用if 语句。如果你想打印十个空格和九个星,那将是两个连续的for 循环。像“一个接一个”一样连续,以防我没有说清楚,在这种情况下我道歉。
    • 我只能打印钻石的左上角。有什么建议么?看看我的代码。谢谢,迈克
    • @Mike,请看我的回答,特别是 "the star count increases by 2" 位 - 你只会增加 1。我的建议是为 numSpacesnumStars 使用单独的变量,所以你不是担心使用公式进行即时计算 - 只是 -1/+2 变宽,+1/-2 在之后的 另一个 循环中变薄。
    • 我想出了适用于用户输入 5 的代码,但它不适用于除 5 以外的任何其他奇数正整数。相反,菱形会变形。我发布了我的代码。我将尝试将我拥有的内容与您的伪代码进行比较。谢谢你的帮助,我真的很感激。
    【解决方案3】:

    您现在可能正在学习 C 入门课程,并且和其他所有人一样,我不鼓励您复制,但这里有一个答案供参考:

    为了简单起见,您只需要知道要打印多少个空格和星号即可。

    顺序如下:[打印空格] [打印星号] [打印空格] [打印'\n']
    观察中间行,我们需要:(0) 个空格,(numStars) 个星号,(0) 个空格
    在上面和下面的行中,我们需要:(1) 个空格,(numStars - 2) 个星星,(1) 个空格
    等等……

    这应该让您感觉要计算空格数,您需要计算与中间行的距离。另请注意,每行远离中间,星数减少 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;
    }
    

    由于我们正在计算当前行和中间行之间的距离,我们需要知道绝对值。 abs 函数是执行此操作的标准 C 函数。

    【讨论】:

      【解决方案4】:

      我对此有点挣扎。也很抱歉,我的最终代码是 C++,而不是严格的 C,因为我已经有 10 年没有使用过 C 了。对于那些试图了解如何为自己解决这个问题的人来说,这里有一个更冗长的解释。在我开始之前,您可以做一件事来帮助自己,从如下声明开始:

      int numStars = 1, numSpaces = 10;

      numSpaces 并不重要,只要它足够小以适合您的屏幕……您可以插入任何数字并稍后进行测试。然后,制定你的算法,然后你可以处理输入。

      此外,星号后的空格数与此问题无关。

      然后,解决如何输出钻石顶部的问题。我使用计数器循环打印空格,直到我打印第一行的空格数,然后第二个循环(非嵌套)打印该行所需的星数。我们知道在第 1 行中,我们需要打印 10 次空格和 1 次星号。

      一旦该行具有所需的空格数和星号,您将转到换行符(“\n”或 endl)。但是下一行你需要多打印 2 个星和少 1 个空格。所以你必须适当地增加/减少。

      当你到达中间那排之前的那一排时,你会停下来。换句话说,当 numSpaces 大于 0 时,top 循环需要继续。在循环的最后一次 pass 结束时,numSpaces 减为 0,但它不会打印有 0 个空格和 n 个星(2 个星)的行对于您开始使用的每个空间)。这发生在你的下一个循环中......

      然后,您可以运行第二个循环,在最后反转您的增量/减量,但其他方面几乎相同。只有这一次,它应该打印 0 个空格和 10n 个星。然后换行,最后将 numStars 减 2,将 numSpaces 加 1。

      如果您尚未使用函数或在实现中不允许使用函数,仅此而已。不过,您可以轻松地调用一个函数,将 numSpaces/numStars 传递给每个循环,以消除重复代码。

      这是我的 C++ 代码:

      #include <iostream>
      
      using namespace std;
      
      int main()
      {
          int     numStars = 1,
                  numSpaces = 10;
      
          while (numSpaces > 0)
          {
              for (int i = 0; i < numSpaces; i++)
              {
                  cout << " ";
              }
              for (int i = 0; i < numStars; i++)
              {
                  cout << "*";
              }
              cout << "\n";
      
              numStars += 2;
              numSpaces--;
          }
          while (numStars > 0)
          {
              for (int i = 0; i < numSpaces; i++)
              {
                  cout << " ";
              }
              for (int i = 0; i < numStars; i++)
              {
                  cout << "*";
              }
              cout << "\n";
              numStars -= 2;
              numSpaces++;
          }
      
          return 0;
      }
      

      【讨论】:

        【解决方案5】:

        我不想给你代码,你应该学习。

        输入的数字将是菱形的宽度,因此请确保在空格和星号之间建立不超过此数字的关系。

        主要思想是从 1 个星号开始,每次递增 2,直到达到输入数字。

        此外,如果用户输入偶数,请采取措施防止出错。

        【讨论】:

        • 我已经写了,如果用户没有输入大于0的正奇数,它会再次要求输入。考虑到用户的输入,只是很难理解何时会打印“*”或“”。
        【解决方案6】:

        这里是matlab的代码

        clear all, clc
        n=input('Input an Odd Number ');
        for i=1:(n+1)/2
            for m=1:(n+1)/2-i
                fprintf(' ');
            end
            for j=1:(2*i)-1
                fprintf('*');
            end
            fprintf('\n');
        end
        for k=i-1:-1:1
            for m=1:(n+1)/2-k
                fprintf(' ');
            end
            for j=1:(2*k)-1
                fprintf('*');
            end
            fprintf('\n');
        end
        

        【讨论】:

          【解决方案7】:
           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();
                  }
          

          【讨论】:

          • 这将 100% 和 10% 帮助您保证。如果您想要更大的用户选择菱形,让他们输入他们的选择并将该选择设置为代替 -2 和 2,例如 for(int row=-choice;row
          【解决方案8】:
          #include<stdio.h>
          main()
          {
          int i,j,k,n;
          scanf("%d",&n);
          n=(n+1)/2;
              for(i=1;i<=n;i++)
              {
                  for(j=n;j>=i;j--)
                      printf(" ");
                  for(k=1;k<=(2*i-1);k++)
                      printf("*");
                  printf("\n");
              }
              for(i=1;i<=(n-1);i++)
              {
                  for(j=0;j<=i;j++)
                      printf(" ");
                  for(k=(2*n-3);k>=(2*i-1);k--)
                      printf("*");
                  printf("\n");
          }
          }
          

          【讨论】:

          • 欢迎使用 stackoverflow,您可能需要在答案中添加一些文本以提高其质量。
          • 你说的文字是cmets?
          • 类似的东西,是的,对您的解决方案的简短说明;它大大丰富了你的答案。
          【解决方案9】:

          嗨,我用更少的行数找到了这个问题的最佳解决方案

          int b=0;
          for(int a=0;b<=50;a=(b<=25) ? a+2 : a-2 ){
              b+=2;
              for(int b=25-a;b>0;b-=2){
                  printf(" ");
              }
              for(int c=0;c<=a;c++){
                  printf("*");
              }
              printf("\n");
          }
          

          【讨论】:

            【解决方案10】:

            Output a diamond in C by asterisk sign

            #include<stdio.h>
            main()
            {
            int n, i, j;
            
            printf("Enter a number: ");
            scanf("%d",&n);
            
            /* Create up arrow. */
            for(i=1; i<=n; i++)
            {   /* Left side. */
                for(j=i; j<=n+1; j++)
                {
                    printf(" ");
            
                }
                for(j=1; j<=1; j++)
                {
                    printf("*");
                }
                /* Middle. */
                for(j=1; j<i-1; j++)
                {
                    printf(" ");
            
                }
            
                /* Right side. */
                for(j=1; j<i; j++)
                {
                    printf(" ");
            
                }
                for(j=1; j<=1; j++)
                {
                    if(i!=n-(n-1))
                        printf("*");
                }
                printf("\n");
            }
            /* Create down arrow. */
            for(i=1; i<=n; i++)
            {   /* Left side. */
                for(j=1; j<=i+2; j++)
                {
                    printf(" ");
            
                }
                for(j=1; j<=1; j++)
                {
                    if(i!=n)
                    printf("*");
                }
                /* Middle. */
                for(j=i; j<n-2; j++)
                {
                    printf(" ");
            
                }
                /* Right side. */
                for(j=i; j<n-1; j++)
                {
                    printf(" ");
            
                }
                for(j=1; j<=1; j++)
                {
                    if(i<n-1)
                    printf("*");
                }
                printf("\n");
            }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-01-27
              • 2014-10-31
              • 1970-01-01
              相关资源
              最近更新 更多