Java - 沙漏

时间:2015-12-05 19:24:14

标签: java hourglass

我只是失踪了一点。我想要的是什么:

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

我得到了什么

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

代码

public class HD404 {
    public static void main(String[] args) {

        int N = StdIn.readInt();
        int x = N*2-1;

        for (int i = 0; i < N; i++) {
            for (int j = i; j > 0; j--) {
                StdOut.print(" ");
            }
            for (int k = 0; k < x; k++) {
                StdOut.print("*");
            }
            x-=2;
            StdOut.println();
        }

        x = 1;
        for (int i = 0; i < N; i++) {
            for (int j = i; j < N-1; j++) {
                StdOut.print(" ");
            }
            for (int k = 0; k < x; k++) {
                StdOut.print("*");
            }
            x += 2;
            StdOut.println();
        }

    }
}

现在我大多只是猜测而且我无法指出我的错误。我在这里缺少什么?

4 个答案:

答案 0 :(得分:1)

问题是你开始使用1个星号(x = 1)而不是3来绘制沙漏的底部。

第二个问题是沙漏的底部只有N-2行,而不是N-1,所以循环应该从1开始而不是0.这是因为带有单个星号的行已经是画在上半部。

更正后的代码:

public static void main(String[] args) {

    int N = StdIn.readInt();
    int x = N*2-1;

    for (int i = 0; i < N; i++) {
        for (int j = i; j > 0; j--) {
            StdOut.print(" ");
        }
        for (int k = 0; k < x; k++) {
            StdOut.print("*");
        }
        x-=2;
        StdOut.println();
    }

    x = 3; // <-- not 1 here, the first line has 3 asterisks
    for (int i = 1; i < N; i++) { // <-- i starts at 1 because the first line was already drawn in the upper half
        for (int j = i; j < N-1; j++) {
            StdOut.print(" ");
        }
        for (int k = 0; k < x; k++) {
            StdOut.print("*");
        }
        x += 2;
        StdOut.println();
    }

}

作为旁注,您可以通过以下观察重写此代码:

  • 要绘制x行,以便我们可以从0循环到x包含(尊重对称)并跳过中间行以便不画两次
  • 对于每一行,都有x列要绘制,它可以是空格或*
  • 对于每一行,仅当当前列位于*min(i, x-i)之间时才会绘制max(i, x-i)(如果我们位于上半部分,i < x-i如果我们在底部,i > x-i)。

代码:

public static void main(String[] args) {
    int N = 4;
    int x = 2 * N - 1;

    for (int i = 0; i <= x; i++) {
        if (i == N) continue; // skip the middle-line for it not to be drawn twice
        for (int j = 0; j < x; j++) {
            System.out.print(j >= Math.min(i, x-i) && j < Math.max(i, x-i) ? "*" : " ");
        }
        System.out.println();
    }
}

示例输出:

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

答案 1 :(得分:1)

问题在于您要求绘制一颗星的代码的第二部分,并且从零开始,您应该从一开始。

解决方案

x = 1;
for (int i = 0; i < N; i++)

应替换为

x = 3;
for (int i = 1; i < N; i++)

答案 2 :(得分:0)

我能想到的最简单的方法可能是阻止你的第一个外环的最后一次迭代,这样你就可以防止显示第一个单星线。

我可能会这样做:

for(int i = 0; i < N && x > 1; i++)
{
    /*Code of the first inner loop*/
}

答案 3 :(得分:0)

对于那些仍在寻找有关沙漏挑战的更简单和更少代码的人。这仅包含 2 个 for 循环。

您可以将其用作参考。

Scanner sc = new Scanner(file);
while(sc.hasNext()) {
    String str =sc.nextLine();
    if (!Pattern.matches("[0-9]+",str) ||( Pattern.matches("[0-9]+",str) &&     Integer.parseInt(str)) <1 )|| ( Pattern.matches("[0-9]+",str) && Integer.parseInt(str)) <1 ) >36) {
        System.out.print("error");
        System.exit(0);
    }
}

}