Bootstrap

### 深入解析:如何构建三角形并求解自顶向下的最小路径和 的基础—(构建三角形)

 

 

#### 一、问题分析

给定一个三角形 `triangle`,要求找出自顶向下的最小路径和。每次移动只能到下一行相邻的节点(当前下标 `i` 或 `i+1`)。例如,三角形如下时:

 

```

   2

  3 4

 6 5 7

4 1 8 3

```

 

 

 

#### 二、代码框架搭建

 

##### 1. 输入处理与三角形构建

```java

Scanner sc = new Scanner(System.in);

List<List<Integer>> triangle = new ArrayList<>();

 

System.out.print("请输入三角形的最大行数: ");

int maxRows = sc.nextInt();

sc.nextLine(); // 清除输入缓冲区中的换行符

 

for (int i = 0; i < maxRows; i++) {

    List<Integer> row = new ArrayList<>();

    System.out.printf("请输入第%d行的元素(用空格分隔):", i + 1);

    String[] input = sc.nextLine().trim().split("\\s+");

    for (String num : input) {

        if (!num.isEmpty()) {

            row.add(Integer.parseInt(num));

        }

    }

    triangle.add(row); // 将当前行添加到三角形中

}

```

 

- **`sc.nextLine()` 的作用**:`nextInt()` 读取输入后不会读取行末的换行符,需要用 `sc.nextLine()` 清除缓冲区。

- **`split("\\s+")`**:按一个或多个空格分割输入,确保处理不规范的输入。

- **逐行构建**:每行的元素存储在 `List<Integer> row` 中,最终形成二维列表 `triangle`。

 

##### 2. 三角形打印

```java

for (int i = 0; i < maxRows; i++) {

    int spaces = maxRows - i - 1;

    for (int j = 0; j < spaces; j++) {

        System.out.print(" ");

    }

    for (int j = 0; j < triangle.get(i).size(); j++) {

        System.out.print(triangle.get(i).get(j) + " ");

    }

    System.out.println();

}

```

 

- **空格计算**:每行前导空格数为 `maxRows - i - 1`,使三角形右对齐显示。

- **逐行输出元素**:遍历每行的元素并打印。

 

---

#### 深入解析代码细节

 

---

 

##### **1. `String[] input` 的含义**

```java

String[] input = sc.nextLine().trim().split("\\s+");

```

- **作用**:  

  这一行代码的作用是将用户输入的一行数据(例如 `"3 4 5"`)按空格分割成一个字符串数组。  

  - `sc.nextLine()`:读取用户输入的一整行(包括空格)。

  - `trim()`:去除输入字符串首尾的空格(避免输入前后误输入空格)。

  - `split("\\s+")`:按一个或多个连续空格分割字符串。例如,输入 `" 6 5 7 "` 会被分割为 `["6", "5", "7"]`。

 

- **示例**:  

  假设用户输入 `" 4 1 8 3 "`(前后有空格),经过处理后:  

  - `trim()` → `"4 1 8 3"`  

  - `split("\\s+")` → `["4", "1", "8", "3"]`  

  最终 `input` 数组保存这些分割后的字符串。

 

---

 

##### **2. `println` 与 `print` 的区别**

| 方法 | 作用 | 示例 |

|-----------------------|----------------------------------------------------------------------|----------------------------------------------------------------------|

| `System.out.print()` | 输出内容后**不换行**,光标停留在输出末尾。 | `System.out.print("A");`<br>`System.out.print("B");` → 输出 `AB` |

| `System.out.println()`| 输出内容后**自动换行**,光标移动到下一行开头。 | `System.out.println("A");`<br>`System.out.println("B");` → 输出:<br>`A`<br>`B` |

 

- **代码中的实际应用**:  

  ```java

  // 打印三角形时,每行元素用 print(保持在一行)

  for (int j = 0; j < triangle.get(i).size(); j++) {

      System.out.print(triangle.get(i).get(j) + " ");

  }

  System.out.println(); // 换行到下一行

  ```

扩展:

1. `printf` 的作用**

`System.out.printf()` 是 Java 中用于**格式化输出**的方法。它的核心功能是通过**格式字符串**控制输出的样式,并动态插入变量值。与 `print` 和 `println` 相比,`printf` 可以更精细地控制输出的对齐方式、数字格式、字符串占位等。

 

- **语法**:  

  ```java

  System.out.printf("格式字符串", 参数1, 参数2, ...);

  ```

 

- **特点**:  

  - **不自动换行**:与 `print` 类似,输出后光标停留在末尾,需手动添加换行符 `%n`。

  - **支持复杂格式化**:例如对齐文本、控制小数位数、日期时间格式等。

 

---

 

##### **2. 格式说明符(Format Specifiers)**

`printf` 通过格式说明符(如 `%d`, `%s`, `%f`)定义变量的输出格式。以下是常见说明符:

 

| 说明符 | 作用 | 示例 | 输出结果 |

|----------|------------------------------|--------------------------|---------------|

| `%d` | 整数(十进制) | `printf("%d", 25);` | `25` |

| `%f` | 浮点数 | `printf("%.2f", 3.1415);`| `3.14` |

| `%s` | 字符串 | `printf("%s", "Hello");` | `Hello` |

| `%n` | 换行符(平台无关) | `printf("A%nB");` | `A`<br>`B` |

| `%5d` | 固定宽度5,右对齐整数 | `printf("%5d", 10);` | ` 10` |

| `%-5s` | 固定宽度5,左对齐字符串 | `printf("%-5s", "Hi");` | `Hi ` |

---

 

##### **3. `triangle.add(row)` 的作用**

```java

List<List<Integer>> triangle = new ArrayList<>();

for (int i = 0; i < maxRows; i++) {

    List<Integer> row = new ArrayList<>();

    // ... 读取用户输入并填充 row ...

    triangle.add(row); // 将当前行添加到三角形中

}

```

- **功能**:  

  将当前行的数据(`row` 列表)添加到二维列表 `triangle` 中,逐行构建完整的三角形数据结构。

  - `triangle` 是一个 `List`,每个元素本身也是一个 `List<Integer>`(表示一行)。

  - `triangle.add(row)` 会将新的一行追加到 `triangle` 的末尾。

 

- **示例**:  

  假设用户输入如下:

  ```

  第1行:2

  第2行:3 4

  第3行:6 5 7

  ```

  则 `triangle` 的结构为:

  ```java

  [

    [2],

    [3, 4],

    [6, 5, 7]

  ]

  ```

 

---

 

#### **代码流程总结**

1. **读取输入**:  

   - 用户输入行数和每行元素。

   - 通过 `split("\\s+")` 处理不规则空格输入。

2. **构建三角形**:  

   - 逐行将数据添加到 `triangle` 中。

3. **打印三角形**:  

   - 通过计算空格数实现右对齐格式。

   - 使用 `print` 和 `println` 控制输出格式。

 

---

 

#### **附:常见问题**

- **为什么用 `split("\\s+")` 而不是 `split(" ")`?**  

  `\\s+` 可以匹配**一个或多个连续空格**,避免空字符串(例如输入 `"3 4"` 会被正确分割为 `["3", "4"]`)。

 

- **为什么需要 `trim()`?**  

  防止用户输入前后误加空格(例如 `" 3 4 "` → 处理后变为 `"3 4"`)。

 

- **`triangle.add(row)` 会覆盖之前的数据吗?**  

  不会。每次循环都会创建一个新的 `row` 对象,`triangle` 保存的是对它的引用,因此各行数据独立。

 

 

 

 

;