
本文详解 Java 中打印二维数组时避免重复输出的关键技巧,重点解决在指定位置插入 {S} 和 {E} 标识符后出现数值冗余的问题,并提供结构清晰、可直接运行的修复方案。
本文详解 java 中打印二维数组时避免重复输出的关键技巧,重点解决在指定位置插入 `{s}` 和 `{e}` 标识符后出现数值冗余的问题,并提供结构清晰、可直接运行的修复方案。
在 Java 中打印二维数组本身很简单,但当需要在特定坐标(如 A* 算法中的起点 S 和终点 E)嵌入自定义标记时,若逻辑处理不当,极易导致同一位置既输出原始值又输出标记——正如提问中所示:{S} 和 {E} 旁多出了额外数字(如 "2 {S} 1 2 2"),破坏了网格语义与可读性。
根本原因在于原代码未对打印逻辑做互斥分支控制:它先无条件输出 M[i][j],再额外判断是否为起点/终点并追加 {S} 或 {E},造成单个单元格被多次打印。
✅ 正确做法是采用 “三选一”互斥打印策略:每个 (i, j) 坐标仅输出一项——要么是 {S},要么是 {E},否则才是 M[i][j]。需用 if-else if-else 链替代独立的 if 判断:
public void create() {
Random rand = new Random();
int min = 2, max = 10;
int a = rand.nextInt(max - min + 1) + min; // 更简洁的随机尺寸写法
int[][] M = new int[a][a];
// 初始化网格:0=空地, 1=草地, 2=沙地, 3=水, 4=墙
for (int i = 0; i < a; i++) {
for (int j = 0; j < a; j++) {
M[i][j] = rand.nextInt(5);
}
}
// 随机生成起点与终点坐标(确保不重合,生产环境建议校验)
int row_start = rand.nextInt(a), col_start = rand.nextInt(a);
int row_end = rand.nextInt(a), col_end = rand.nextInt(a);
// 可选:避免起点终点重合(增强鲁棒性)
while (row_start == row_end && col_start == col_end) {
row_end = rand.nextInt(a);
col_end = rand.nextInt(a);
}
// ✅ 正确打印:每格只输出一个内容
for (int i = 0; i < a; i++) {
for (int j = 0; j < a; j++) {
if (row_start == i && col_start == j) {
System.out.print("{S}\t");
} else if (row_end == i && col_end == j) {
System.out.print("{E}\t");
} else {
System.out.print(M[i][j] + "\t");
}
}
System.out.println(); // 换行更清晰(比 print("\n") 推荐)
}
}? 关键注意事项:
- 逻辑互斥性:必须使用 else if 而非多个独立 if,否则当起点与终点坐标相同时(虽概率低),会触发两次输出;即使不重合,原逻辑也会先打数值再打标记,造成冗余。
- 格式一致性:所有分支均使用 \t 制表符对齐,避免因 {S} 字符长度不同导致列错位;若需严格等宽,可考虑 String.format("%-3s", ...) 控制宽度。
- 可维护性增强:将 M[i][j] 打印统一放在 else 分支,语义明确——“其余位置显示数值”,符合直觉且易于扩展(例如后续添加障碍物符号 {X})。
- 健壮性提示:实际路径搜索场景中,应确保起点与终点位于有效网格内(本例已满足),并建议加入重复坐标校验,防止无效输入。
通过这一重构,输出将严格符合预期网格结构,例如:
1 0 4 0
2 {S} 1 2
4 4 {E} 0
2 0 3 3 每一行 a 个元素,每列对齐,{S} 与 {E} 精准覆盖对应位置,无任何冗余数字——为后续 A* 算法的可视化调试与逻辑验证奠定可靠基础。











