Java程序: Generate christmas tree : formatting?

标签 java

所以在我的计算机科学课上,我们有一个小硬件问题,大约一周后才到期,除了一小部分之外,它几乎可以工作。这是作业:

Write a program named ChrisTree that produces images of Christmas trees as output. It should have a method with two parameters: one for the number of segments in the tree and one for the height of each segment. For example, the tree shown here on the left has three segments of height 4 and the one on the right has two segments of height 5.

Image of two ASCII Christmas trees, with the left tree having three triangles, and the right having two triangles.

所以我的代码可以工作,除了一些树上的最后一行和树干都相差一个空格的树。我似乎无法在不开新洞的情况下堵住这个洞。有人看到问题可能的“根源”吗? PS树的段和高度是通过改变类常量来改变的(我知道,这是改变它们的一个糟糕的方法,但这就是这个人想要的)(我知道它也可能非常多余)

public class ChrisTree {
  public static final int SEGMENTS = 4;
  public static final int HEIGHT = 4;
  public static void main(String[] args){
  makeTree();
  }
  // makeTree: code that prints the tree; params: num. of segments of tree, height of tree segments
  public static void makeTree(){
  // maxStars: calculation the length of each line which is the sum of spaces and stars for any line
    int maxStars = 2*HEIGHT+2*SEGMENTS-3;
    // maxStr: master variable string that will be changed and printed for each line
    String maxStr = "";
    // populates maxStr will spaces; will be used with substring to generate needed spaces
    for (int len=0; len < maxStars; len++){
      maxStr+=" ";
    }
    // loops once per segment
    for (int i=1; i <= SEGMENTS; i++){
      // starStr: variable string that changes perline that holds the stars

      // populates starStr with stars
      // loops through each line
      for (int line=1; line <= HEIGHT; line++){
        String starStr = "";
        for (int j=1; j <= 2*line+2*i-3; j++){
          starStr+="*";
        }
        for (int space=0; space <= maxStars-(HEIGHT+line+i); space++){
          starStr = " " + starStr;
        }
        System.out.println(starStr);
      }
    }

    for (int i=0; i <= maxStars/2;i++){
      System.out.print(" ");
    }
    System.out.print("*\n");
    for (int i=0; i <= maxStars/2;i++){
      System.out.print(" ");
    }
    System.out.print("*\n");
    for (int i=0; i <= maxStars/2-3;i++){
      System.out.print(" ");
    }
    System.out.print("*******\n");
  }
}

最佳答案

我为做明显的家庭作业问题辩护,这里的解决方案太伤害我的眼睛了。 (我知道这些是标准作业问题,我在 80 年代用 Pascal 做过)。

package com.edwinbuck.christmas;

/**
 * Draws a ChristmasTree.

 * @author Edwin Buck
 */
public class ChristmasTree {

    public static final int SEGMENTS = 4;
    public static final int HEIGHT = 4;

    public static void main(String[] args) {
        int maxSize = 1 + 2 * (SEGMENTS - 1) + 2 * (HEIGHT - 1);
        // for each segment beyond zero, we need 2 more asterisks.
        for (int segmentContrib = 0; segmentContrib < 2 * SEGMENTS; segmentContrib += 2) {
            // for each segment slice beyond zero, we need 2 more asterisks.
            for (int sliceContrib = 0; sliceContrib < 2 * HEIGHT; sliceContrib += 2) {
                drawCentered(maxSize, 1 + segmentContrib + sliceContrib);
            }
        }
        // draw the trunk
        drawCentered(maxSize, 1);
        drawCentered(maxSize, 1);
        // draw the base
        drawCentered(maxSize, 7);
    }

    /**
     * Draws a line of asterisks, centered within size spaces.
     *
     * @param size The size to center on.
     * @param asterisks The number of asterisks to draw.
     */
    private static void drawCentered(int size, int asterisks) {
        int before = (size - asterisks) / 2;
        int after = size - before - asterisks;
        print(before, " ");
        print(asterisks, "*");
        print(after, " ");
        System.out.println();
    }

    /**
     * Draws a character a number of times.
     *
     * @param count The number of time to draw the character.
     * @param character The character to draw.
     */
    private static void print(int count, final String character) {
        for (int i = 0; i < count; i++) {
            System.out.print(character);
        }
    }

}

关键是要认识到所有行都是大小可变的居中星号。一旦你这样做了,那么你只需要找出绘制部分的循环(以及最大线条尺寸)。

最大行尺寸由最底部部分控制。每个输入(SEGMENTSHEIGHT)都需要从“从 1 开始计数”转换为“从 0 开始计数”。每个附加段都会使星号大小增加 2,每个附加切片也是如此。该树必须至少有一个星号,即沿着中心延伸的星号(树干)。由此得出公式

 1 + 2*(SEGMENTS-1) + 2(HEIGHT-1)

许多人已经简化为

 2*SEGMENTS + 2*HEIGHT - 3

我没有简化它,因为它隐藏了意图,一旦丢失就很难在代码中恢复。

然后,在遍历循环时,我决定让贡献者的大小增加两倍。它使其余的数学变得更容易,因为我们不必将“神奇”公式和数学放在奇怪的地方。这意味着我们可以使用参数 1 + segmentContrib + sliceContrib 重用 drawCentered(...) ,其中其他两个变量是段和切片“星号”贡献。

最后,我们画一个由两个垂直星号组成的树干和底座。

关于Java程序: Generate christmas tree : formatting?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25685949/

相关文章:

java - selenium - 需要从动态加载的分区中找到一个元素并单击它

java - 编写返回数组后半部分的方法 secondaryHalf。不能使用快捷方式,只能使用for循环

java - 信用卡验证字符解析问题

java - 我需要解析java中不同数据类型的其他集合中的集合内容

Java 模块 Jigsaw JPMS 模块化由于 org.apache.juli.logging.Log 而阻止 Spring 容器启动 Rest Controller

java - 动态调整 JScrollPane 的大小?

java - Android Firebase 数据库异常 : not define a no-argument constructor

java - Android - 如何在每次打开应用程序时启动完全相同的 Activity ?

java - 找出前N个最流行的元素

java - GWT RequestFactory - 向代理类添加自定义方法?