如何绘制双空ASCII菱形?

How to draw a double empty ASCII rhombus?

如何绘制带星号的双空菱形?我实现了菱形本身,但我不明白如何使它加倍。

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

我的代码:

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

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

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...

`

您只需在每一行中再重复一次行生成器函数,即可添加更多菱形。

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

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

输出(按要求)

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

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

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

我们通过使用重复 nString:

的方法来简化代码
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)

调用

想象一个坐标平面,画出菱形函数的图形:

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