【问题标题】:How to draw a double empty ASCII rhombus?如何绘制双空ASCII菱形?
【发布时间】:2021-06-27 18:59:40
【问题描述】:

如何用星号画出双空菱形?我已经实现了菱形本身,但我不明白如何使它加倍。

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

我的代码:

int i, j, n = 6;
String str = "";
for (i = 1; i <= n; i++) {
    for (j = n; j > i; j--)
        str += " ";
    str += "*";
    for (j = 1; j < (i - 1) * 2; j++)
        str += " ";
    if (i == 1)
        str += ("\n");
    else
        str += ("*\n");
}
for (i = 2; i <= n; i++) {
    for (j = 1; j < i; j++)
        str += " ";
    for (j = 1; j <= n * 2 - (2 * i - 1); j++)
        if (i == 0 || j == 1 || j == n * 2 - (2 * i - 1))
            str += "*";
        else
            str += " ";
    str += "\n";
}
System.out.println(str);

【问题讨论】:

    标签: java ascii-art


    【解决方案1】:

    将您的代码分成两个函数,生成一行带有一个或两个星号的行。 此函数应将字符串、菱形宽度和星号位置作为参数,并返回一个字符串,并将创建的行附加到作为参数给出的字符串后。此外,创建的线应始终具有相同的宽度,这意味着在右侧也用空白填充。并且它不能附加换行符。 所以你的代码看起来像:

    private final static int WIDTH = 11;
    ...
    StringBuilder rhombusBuilder = new StringBuilder();
    String line = "";
    
    line = singleAsteriskLine( line, WIDTH ); // outputs "     *     "
    line = singleAsteriskLine( line, WIDTH ); // outputs "     *          *     "
    rhombusBuilder.append( line + "\n" );
    for (int pos = 0; pos < (WIDTH - 1) / 2; ++pos) {
        line = doubleAsteriskLine( "", WIDTH, pos ) // pos = 0 "   * *    "
        line = doubleAsteriskLine( line, WIDTH, pos ) // pos = 5 "*         **         *"
    // append to stringbuilder
    } 
    // same backwards....
    // append a single asterisk line again...
    

    `

    您可以通过在每一行中再重复一次行生成器函数来添加更多菱形。

    【讨论】:

      【解决方案2】:

      我会为所需的输出计算一个位掩码,计算适当的整数值,然后用它来驱动一切。喜欢,

      int[] bitmask = { 65568, 163920, 278664, 532740, 1053186, 2100225,
              1053186, 532740, 278664, 163920, 65568 };
      for (int v : bitmask) {
          for (int j = 0; j < 22; j++) {
              System.out.print((v & (1 << j)) == 0 ? ' ' : '*');
          }
          System.out.println();
      }
      

      输出(按要求)

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

      【讨论】:

        【解决方案3】:

        我会将您的代码重构为一个返回单行菱形的方法,包括末尾和开头的空格:

        String rhombLine(int i, int n)
        {
            String side = repeat(" ", n-i);
            String mid = "*";
            if (i > 1)
            {
                mid += repeat(" ", (i - 1) * 2 - 1);
                mid += "*";
            }
            return side + mid + side;
        }
        

        我们通过使用重复n 复制String 的方法来简化代码:

        static String repeat(String s, int n)
        {
            String r = "";
            for(int i=0; i<n; i++) r += s;
            return r;
        }
        

        如果您使用的是 Java 11,则可以改用 String.repeat() 方法。

        现在您可以在每行打印两份菱形线:

        void rhombus(int n)
        {
            for(int i=1; i<=n; i++)
                System.out.println(repeat(rhombLine(i, n), 2));         
        
            for(int i=n-1; i>0; i--)
                System.out.println(repeat(rhombLine(i, n), 2));                 
        }
        

        作为替代方案,有一个使用递归的好技巧,这意味着您只需要生成每一行一次:

        void rhombus(int i, int n)
        {       
            String line = repeat(rhombLine(i, n), 2);       
            
            System.out.println(line);
            
            if(i == n) return;
            
            rhombus(i+1, n);
            
            System.out.println(line);
        }
        

        最初会通过rhombus(1, 6)调用

        【讨论】:

          【解决方案4】:

          想象一个坐标平面并以菱形形式绘制函数图:

          Math.abs(y - n) + Math.abs(x - n) == n
          

          Try it online!

          零点在左上角,轴向下向右:

          // size of the rhombus
          int n = 6;
          // number of rhombuses
          int m = 4;
          // vertical axis
          for (int y = 0; y <= 2 * n; y++) {
              // horizontal axis
              for (int x = 0; x < 2 * n * m + m; x++) {
                  // current rhombus
                  int k = x / (2 * n + 1);
                  // center of the rhombus
                  int c = (2 * k + 1) * n + k;
                  // check if this point is on the rhombus
                  if (Math.abs(y - n) + Math.abs(x - c) == n)
                      System.out.print("*");
                  else
                      System.out.print(" ");
              }
              System.out.println();
          }
          

          输出:

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

          另见:Output an ASCII diamond shape using loops

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多