Java树形图形程序修复:树干计算、星点统计及循环执行问题
修复你的树形打印Java程序问题
我看了你的代码,发现几个关键问题导致第二次运行统计错误、树干显示异常,下面是修复后的完整代码,以及详细的修改说明:
修复后的主测试类(Main.java)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); while (n % 2 == 0 || n < 0) { System.out.println("请输入一个奇数"); n = sc.nextInt(); // 调整顺序:先提示再读取,避免逻辑颠倒 } /** * 第一次运行,长度为9 */ Triangle_new triangle = new Triangle_new(n); triangle.display_triangle(); System.out.println(); System.out.println("Total number of stars = " + triangle.get_stars()); System.out.println("Total number of dots = " + triangle.get_dots()); System.out.println(); Triangle_new tree = new Triangle_new(n); tree.display_tree(); System.out.println(); /** * 第二次运行,长度为11 */ System.out.println("Now the length will be set to 11."); System.out.println(); Triangle_new triangle2 = new Triangle_new(11); triangle2.display_triangle(); System.out.println(); System.out.println("Total number of stars = " + triangle2.get_stars()); System.out.println("Total number of dots = " + triangle2.get_dots()); System.out.println(); Triangle_new tree2 = new Triangle_new(11); tree2.display_tree(); } }
修复后的核心类(Triangle_new.java)
public class Triangle_new { private int length; private int lines; // 三角形的行数,由length直接计算得出 private int starsCounter; private int dotsCounter; //主构造函数 public Triangle_new(int n) { if (n % 2 == 0 || n < 1) { throw new IllegalArgumentException("长度必须是正奇数"); } this.length = n; this.lines = (length + 1) / 2; // 直接计算行数:比如length=9时行数为5,length=11时为6 resetCounters(); } // 重置计数器,避免多次打印时累计旧数据 private void resetCounters() { starsCounter = 0; dotsCounter = 0; } // 打印三角形方法 public void display_triangle() { resetCounters(); int currentStars = 1; // 用局部变量跟踪当前行星号数量,避免污染实例变量 for (int line = 0; line < lines; line++) { int dotsPerSide = (length - currentStars) / 2; // 打印左侧点 for (int i = 0; i < dotsPerSide; i++) { System.out.print("."); dotsCounter++; } // 打印星号 for (int i = 0; i < currentStars; i++) { System.out.print("*"); starsCounter++; } // 打印右侧点 for (int i = 0; i < dotsPerSide; i++) { System.out.print("."); dotsCounter++; } System.out.println(); currentStars += 2; } } public void set_length(int l) { if (l % 2 == 0 || l < 1) { throw new IllegalArgumentException("长度必须是正奇数"); } this.length = l; this.lines = (length + 1) / 2; resetCounters(); } // 打印带树干的树形 public void display_tree() { resetCounters(); // 先打印三角形部分 display_triangle(); // 计算树干的两侧点数量(树干为1个星号) int trunkDotsPerSide = (length - 1) / 2; // 树干行数取三角形行数的一半(向下取整) int trunkLines = lines / 2; for (int i = 0; i < trunkLines; i++) { // 打印左侧点 for (int j = 0; j < trunkDotsPerSide; j++) { System.out.print("."); dotsCounter++; } // 打印树干星号 System.out.print("*"); starsCounter++; // 打印右侧点 for (int j = 0; j < trunkDotsPerSide; j++) { System.out.print("."); dotsCounter++; } System.out.println(); } } public int get_length() { return length; } public int get_lines() { return lines; } public int get_stars() { return starsCounter; } public int get_dots() { return dotsCounter; } }
关键修改说明
- 分离变量职责:原代码把临时计算变量和计数器变量混用,导致逻辑混乱。现在用局部变量处理每行的星号/点计算,实例变量只保存固定属性和统计值。
- 重置计数器机制:添加
resetCounters()方法,每次打印前重置统计值,彻底解决第二次运行时数据累计错误的问题。 - 修复树干打印逻辑:原代码的树干只打印一次前置点就换行,导致星号偏移。现在每行都完整打印「前置点+星号+后置点」,确保树干居中显示。
- 简化行数计算:三角形行数可以通过
(length +1)/2直接算出,不需要循环统计,更高效且不易出错。 - 输入合法性校验:在构造函数和
set_length中添加参数检查,避免传入无效的偶数或负数。 - 修正主类提示顺序:原代码先读取输入再提示,逻辑颠倒,现在调整为先提示后读取,符合用户交互习惯。
这样修改后,无论是第一次运行还是第二次设置长度为11,都能正确打印三角形和树干,星号、点的统计数量也完全准确。
内容的提问来源于stack exchange,提问作者Felix
相关产品推荐
相关产品推荐

