目录
题目
实现字母金字塔,通过键盘输入字符来控制层数,如输入D,则打印下面图形
A
ABA
ABCBA
ABCDCBA
题目解析
题目理解
由题目中的图形可知,主要是打印字母的金字塔,这个金字塔怎么构成的勒:
- 每一行都是以首字母A开始,递增后到每一行的最大值后,又递减到首字母A结束;
- 行数等于输入字母-首字母数即:char(D)-A+1;
- 每一行最中间的字母以此增加,到输入字母char(D)结束;
- 每一行的最大值跟行数成现行关系:A+i+x(系数);
- 假如不是最后一行,那么在输入字母之前需要先有空格;
- 每一行的字母数量是行数*2-1个;
如果把这个字母金字塔看成一个整体,那么我们不但需要判断打印空格的时机,还要判断打印递增字母的时机,还得判断递减字母的时机,会导致思路很复杂。这种复杂的想法不适合初学者思考,因此我这边建议将图形分开成三份后再做处理。
假定:
- 1)输入的变量元素(chr)就是D,首元素就是A;
- 2)那么需要打印的行数就是len= D-A+1=4;
- 3)i代表行数,j代表列数;
空格图-坐标解析
i/j 0 1 2 3 0 * * * 1 * * 2 * 3 空格坐标图(以*表示占位)
根据空格图我们知道需要打印的空格以代码表示为:
c
for (int i=0;i<=len-1;i++){ //从坐标图看从i=0开始就有,到3结束,共4列,也就等于len-1=4-1=3
for(int j=0;j<len-1-i;j++){ //从坐标图看从j=0开始,第一行打印到len-1-1结算,之后以此少打一个,即到j=(len-1)-i结束;
printf(" "); //打印空格;
}
printf("\n"); //一行打印完后进行换行
}
字母递增图-坐标解析
i/j 0 1 2 3 0 A 1 A B 2 A B C 3 A B C D 字母递增图
空格已经打印完了的情况下,即空格已经占位好了,那么这个字母递增图从实际写代码出发会进行变种到如下所示:
| i/j | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 0 | A | |||
| 1 | A | B | ||
| 2 | A | B | C | |
| 3 | A | B | C | D |
字母递增图修订
根据坐标图我们知道需要打印递增字母以代码表示为:
c
for (int i=0;i<=len-1;i++){ //从坐标图看从i=0开始就有,到3结束,共4列,也就等于len-1=4-1=3
for(int j=0;j<=i;j++){ //从坐标图看从j=0开始,每一行都是i=j的时候结束;
printf('A'+j); //打印字母,以首字母A开始,每一列加j;
}
printf("\n"); //一行打印完后进行换行
}
字母递减图-坐标解析
i/j 0 1 2 3 0 1 A 2 B A 3 C B A 字母递减坐标图
根据坐标图我们知道需要打印的代码表示为:
c
for (int i=0;i<=len-1;i++){ //从坐标图看从i=0开始就有,到3结束,共4列,也就等于len-1=4-1=3
for(int j=1;j<=i;j++){ //从坐标图看从j=1开始,每一行都是i=j的时候结束;
printf('A'+i-j); //打印字母,每次结束的时候都是A,然后以此往坐标的左边加1,所以是-j,每一行又都是i=j时结束,所以加了一个i,带入公式验证两行无误即可编译验证;
}
printf("\n"); //一行打印完后进行换行
}
代码汇总验证
代码汇总
c
int main(int argc, char const *argv[])
{
char chr;
printf("input char A~Z/a~z/0-9:");
scanf("%c",&chr);
char chr_sop;
int len;
switch (chr)
{
case 'A'...'Z': len =chr-'A'+1; chr_sop='A'; break;
case 'a'...'z': len =chr-'a'+1; chr_sop='a'; break;
case '0'...'9': len =chr-'0'+1; chr_sop='0'; break;
default: printf("input error\n");
return 0;
break;
}
for (char i=0;i<=len-1;i++){
for(int j=0;j<(len-1)-i;j++){
printf(" ");
}
for(int j=0;j<=i;j++){
printf("%c",chr_sop+j);
}
for(int j=1;j<=i;j++){
printf("%c",chr_sop+i-j);
}
printf("\n");
}
return 0;
}
我这里汇总的代码与前面的图解代码几乎一模一样。
只是做了以下优化:
- 1)将字符的长度与首字符用变量len和chr_sop表示,方便处理不同的类型;
- 2)用switch ...case...语句将输入的字符分类,扩展到可以处理三种类型的金字塔;
- 3)在字符完全不合规的情况下,直接return 退出执行代码;
- 其余地方与图解一样,甚至连坐标的起始都一样。
终端运行验证

可以看到输出的结果与题目一模一样,且可以打印超过D大小的金字塔;
坐标图解法的好处
建议
- 1)初学者做图形打印练习的时候都先画坐标图,再写代码;
- 2)初学者的坐标都以i/j都以0(或1)开始,自加形式,然后去找结束条件;
好处
可以从坐标图清晰看出:
- 图形的i有几列,第一层循环很清晰,****基本可以无脑写(int i=0;i<=x;i++);
- 每一行的打印开始位置,且都是自增的情况下,第二层循环可以无脑先写成(for(int j=0(或则其他,根据图来);循环条件;j++))。然后就再去找循环的条件即可;
- 可以很清晰的看出来每行的打印规律,而且就算第一次没把规律找对,也可以很对照坐标很轻松验证,再去调整;
总结一下好处就是:
- 1)循环体很好写出来:
- 不用纠结循环体的写法;
- 只要去找循环条件即可;
- 都是自增,不用多余考虑是否需要自减;
- 2)对比思路很清晰 ,顺带梳理了写代码的思路;