核心工具:range()函数
在开始分析五种图案之前,需要先理解range('A', 'Z')的作用。这个函数生成一个包含从A到Z所有大写字母的数组,数组下标0对应'A',下标1对应'B',以此类推。后面所有示例中的$alpha[$i]或$alpha[$j]都是从这个数组中取字母。
关于range()函数的一个经验:它支持字母和数字两种范围,但字母范围只能从A到Z或a到z,不能跨大小写。如果需要更多字母,可以用range(’A‘, ’Z‘)拿整个字母表,然后通过循环条件控制取前几个。
Pattern 1:倒三角形(同字母竖列递减)
这是基础倒三角形,每行使用同一个字母,从上到下每行字母个数递减,字母按行递增。
<?php
$alpha = range('A', 'Z');
for ($i = 0; $i < 5; $i++) {
for ($j = 5; $j > $i; $j--) {
echo $alpha[$i]; // 注意:用的是$i,不是$j
}
echo "<br>";
}
?>
输出:
AAAAA
BBBB
CCC
DD
E
规律拆解:
-
外层
$i=0时输出$alpha[0]即A,内层循环5次 → 5个A -
外层
$i=1时输出$alpha[1]即B,内层循环4次 → 4个B -
依此类推,直到
$i=4时输出1个E
这里的关键是内层循环控制次数(5、4、3、2、1),外层循环控制输出的字母(A、B、C、D、E)。
Pattern 2:正三角形(同字母竖列递增)
每行使用同一个字母,从上到下每行字母个数递增,字母按行递增。
<?php
$alpha = range('A', 'Z');
for ($i = 0; $i < 5; $i++) {
for ($j = 0; $j <= $i; $j++) { // 条件改为 $j <= $i
echo $alpha[$i];
}
echo "<br>";
}
?>
输出:
A
BB
CCC
DDDD
EEEEE
规律拆解:
-
外层
$i=0时,内层$j=0到0 → 1次 → 1个A -
外层
$i=1时,内层$j=0到1 → 2次 → 2个B -
外层
$i=4时,内层$j=0到4 → 5次 → 5个E
与Pattern 1相比,内层循环的方向和边界条件发生了变化,从递减变成了递增。
个人经验:Pattern 1和Pattern 2对比学习效果很好。两者区别仅在于内层循环的条件——一个从大到小递减,一个从小到大递增。理解了这两个,就掌握了控制输出数量的基本手段。
Pattern 3:正三角形(字母横向递增)
每行输出多个不同字母,从左到右按字母表顺序排列,行数决定该行输出字母的数量。
<?php
$alpha = range('A', 'Z');
for ($i = 0; $i < 5; $i++) {
for ($j = 0; $j <= $i; $j++) {
echo $alpha[$j]; // 注意:这里用的是$j,不是$i
}
echo "<br>";
}
?>
输出:
A
AB
ABC
ABCD
ABCDE
规律拆解:
-
第1行(
$i=0):$j=0→$alpha[0]= A -
第2行(
$i=1):$j=0,1→ A、B -
第3行(
$i=2):$j=0,1,2→ A、B、C -
第5行(
$i=4):$j=0~4→ A、B、C、D、E
这里的变化是:每行输出的字母不再相同,而是从A开始递增到某个字母。所以内层循环的$alpha[$j]让字母随列号变化,而非固定的行号。
Pattern 4:倒三角形(字母横向递减)
每行输出多个不同字母,从特定的字母开始递减排列。
<?php
$alpha = range('A', 'Z');
for ($i = 0; $i < 5; $i++) {
for ($j = 4; $j >= $i; $j--) { // $j从4递减到$i
echo $alpha[$j];
}
echo "<br>";
}
?>
输出:
EDCBA
EDCB
EDC
ED
E
规律拆解:
-
第1行(
$i=0):$j=4,3,2,1,0→ E、D、C、B、A -
第2行(
$i=1):$j=4,3,2,1→ E、D、C、B -
第5行(
$i=4):$j=4→ E
这个图案的特点是:每行都从字母E开始倒序输出,每行少一个末尾字母。
Pattern 5:居中对齐的字母金字塔(带空格)
这是一个复杂一些的图案,需要在每行前面输出空格来实现居中对齐效果。
<?php
$alpha = range('A', 'Z');
for ($i = 5; $i >= 1; $i--) {
// 第一部分:输出前置空格
for ($j = 0; $j <= $i; $j++) {
echo ' ';
}
$j--; // 调整$j的值用于下面的循环
// 第二部分:输出字母(从A开始递增)
for ($k = 0; $k <= (5 - $j); $k++) {
echo $alpha[$k];
}
echo "<br>";
}
?>
输出:
A
AB
ABC
ABCD
ABCDE
规律拆解:
-
外层循环
$i从5递减到1,控制行数 -
空格数量:每行先输出若干空格,使字母部分向右移动,形成居中对齐效果
-
字母部分:每行从A开始输出递增字母,数量与行号有关
个人经验:Pattern 5是这组练习中相对复杂的一个。第一次看这个代码可能会对$j--和5-$j的计算感到困惑。实际上,原作者用了一种略带技巧的方式来算字母数量。如果用更直白的写法,可以这样:
<?php
$alpha = range('A', 'Z');
for ($row = 1; $row <= 5; $row++) {
// 输出空格:5 - $row 个
for ($space = 1; $space <= 5 - $row; $space++) {
echo ' ';
}
// 输出字母:从A到对应的字母
for ($letter = 0; $letter < $row; $letter++) {
echo $alpha[$letter];
}
echo "<br>";
}
?>
这种写法更符合直觉:空格数 = 总行数 - 当前行号,字母数 = 当前行号。
本节课程知识要点
| 知识点 | 说明 |
|---|---|
| 嵌套循环 | 外层循环控制行数,内层循环控制每行的输出内容 |
| 循环边界调整 | 修改内层循环的条件和步进,可以改变输出数量 |
| 下标选择 | $alpha[$i]输出固定字母(行变列不变),$alpha[$j]输出递增字母(行变列也变) |
| 前置空格 | 通过输出空格字符实现内容居中对齐 |
| range()数组 | 预先生成字母表,通过下标访问 |
五种图案的对比
| 图案 | 形状 | 每行字母是否相同 | 字母变化规律 |
|---|---|---|---|
| Pattern 1 | 倒三角 | 是 | 行号增大,字母前进 |
| Pattern 2 | 正三角 | 是 | 行号增大,字母前进 |
| Pattern 3 | 正三角 | 否 | 每行从A开始递增 |
| Pattern 4 | 倒三角 | 否 | 每行从E开始递减 |
| Pattern 5 | 居中对齐正三角 | 否 | 每行从A开始递增,前面加空格 |
常见问题与排查
问题1:输出结果中字母数量正确但字母内容不对
-
可能原因:
$alpha[$i]和$alpha[$j]用混了 -
检查:明确当前行是需要固定字母还是变化字母
问题2:Pattern 5的空格数量不对,图案偏左或偏右
-
检查空格循环的次数计算是否正确
-
常见错误:用
5-$i还是$i-1,需要根据外层循环的起始值计算
问题3:内层循环条件中的<=和<用错
-
影响:输出个数会差1个
-
建议:先用小数字(比如3行)测试,确认边界值
个人经验与建议
关于字母图案练习,有几点想分享:
第一,不要死记代码,要理解规律。每一种图案都可以通过调整循环边界和下标选择来实现。理解了$i和$j的角色,就能自己推导出不同图案的写法。
第二,从简单到复杂逐步尝试。先写好Pattern 1和Pattern 2,掌握了基础后,再尝试Pattern 3和Pattern 4。Pattern 5涉及空格控制,可以单独练习。
第三,学会用自己的思路重写。Pattern 5的原写法比较绕,我重写了一个更直观的版本。在学习过程中,如果觉得别人的代码难懂,尝试用自己的方式实现相同的效果,这是加深理解的有效方式。
第四,这些练习的价值在于培养循环思维。在项目中,生成图案的需求很少见,但嵌套循环处理二维数据(表格、矩阵、网格)的情况很常见。图案练习帮你建立的感觉,在那些场景中同样适用。