首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java程序:生成圣诞树:格式化?

Java程序:生成圣诞树:格式化?
EN

Stack Overflow用户
提问于 2014-09-05 12:30:23
回答 2查看 13.2K关注 0票数 1

所以在我的CS课上,我们有一个小的hw问题,这个问题在一个星期左右才到期,除了一小部分外,它几乎是有效的。这是一项任务:

编写一个名为ChrisTree的程序,生成圣诞树的图像作为输出。它应该有一个包含两个参数的方法:一个表示树中的段数,另一个表示每个段的高度。例如,左边的树有三段高4,右边的树有两段高5。

因此,我的代码可以工作,除非在一些树上,树的最后一行和树干都由一个空格隔开。我似乎不能不做一个新的洞就把那个洞堵住。有没有人看到这个问题的“根源”?树段和树高是通过改变类常量而变化的(我知道,这是改变类常量的糟糕方法,但这正是这个人想要的)(我知道它可能也是可怕的冗余)。

代码语言:javascript
复制
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");
  }
}
EN

回答 2

Stack Overflow用户

发布于 2015-03-22 06:00:08

作为我对做作业问题的辩护,这里的解决方案太伤我的眼睛了。(我知道这是标准的家庭作业问题,我早在80年代就在帕斯卡做过。)

代码语言:javascript
复制
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计数”。每个额外的段添加两个星号大小,每个额外的切片也是如此。这棵树必须至少有一个星号,其中一个(树干)沿着中心运行。这就引出了公式

代码语言:javascript
复制
 1 + 2*(SEGMENTS-1) + 2(HEIGHT-1)

许多人已经简化为

代码语言:javascript
复制
 2*SEGMENTS + 2*HEIGHT - 3

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

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

最后,我们画了一个树干两个垂直星号和底部。

票数 1
EN

Stack Overflow用户

发布于 2015-03-22 04:43:10

我知道现在已经很晚了,但我只是写了这篇文章,它起了作用。

代码语言:javascript
复制
public class ChrisTree {
    public static final int SEGMENTS = 4;
    public static final int HEIGHT = 4;

    public static void main(String[] args) {
        makeTree();
    }

    public static void makeTree() {
        int maxStars = 2 * HEIGHT + 2 * SEGMENTS - 3;
        String maxStr = "";
        for (int l = 0; l < maxStars; l++) {
            maxStr += " ";
        }
        for (int i = 1; i <= SEGMENTS; i++) {
            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.println(" " + "*" + " ");
        for (int i = 0; i <= maxStars / 2; i++) {
            System.out.print(" ");
        }
        System.out.println(" " + "*" + " ");
        for (int i = 0; i <= maxStars / 2 - 3; i++) {
            System.out.print(" ");
        }
        System.out.println(" " + "*******");
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25685949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档