前言 昨天在和朋友看电影的时候,一个在南开大学就读的高中同学给我发来这样一道题目:
输出一个大小为n的金字塔,金字塔是一个等腰三角形,大小为n的金字塔底层有n个*,每一层*的个数都是下一层的个数减2,第一层的*在最中央。因为这个问题太简单了,所以要求金字塔的顶可以朝上下左右四个方向。
当时正是电影最为精彩的部分,所以我并没有对这道题太过在意。我只是大致看了一下,然后回复同学说“我现在在看电影”就退出了QQ的聊天框。到了晚上,我突然想起了还有这么一道题,也突然觉得这道题可以让我的无聊的晚上变得有趣起来。高中同学发来这道题的时候说要用C++编写程序,但是我对C++一无所知。最后,我还是决定试一下,用C语言和Python来完成这道题目。
初步的想法 在离开实验室走回宿舍的路上,我一直在思考这道题该如何去完成。我想起了之前在刷Python编程练习100例的时候写过的类似的一个程序,使用Python 3.6编写如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from sys import stdout for i in range(4): for j in range(2 - i + 1): stdout.write(' ') for k in range(2 * i + 1): stdout.write('*') print() for i in range(3): for j in range(i + 1): stdout.write(' ') for k in range(4 - 2 * i + 1): stdout.write('*') print()
输出结果如下:
1 2 3 4 5 6 7 * *** ***** ******* ***** *** *
当时写这个编程练习的时候,我的想法是先把图形分成前4行和后3行两部分来看,它们分别有不同的规律,可以利用for循环的嵌套,第1层控制行,第2层控制列,实现金字塔图形的输出。这样看来,同学问我的那道题,只不过是这道题的“进阶版”。 题目中要求用户键入w/a/s/d来输出不同塔尖方向的金字塔。对于这一点,我们可以把w/a/s/d四个方向分成四部分,使用if-else if-else语句(或者在C语言中使用switch语句,Python没有switch语句)分类讨论。
用C语言实现 如果觉得金字塔的规律不容易找出来,我们不妨找一张草稿纸,在纸上画一画。这里省略掉找规律的过程。程序源代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include <stdio.h> #include <stdlib.h> int main (void) { int num, i, j, h; char direction; printf ("请输入塔底长度和塔尖方向(w/a/s/d),使用空格分隔开:"); scanf ("%d %c", &num, &direction); h = (num + 1) / 2; switch (direction) { case 'w': for (i = 1; i <= h; i++) { for (j = 1; j <= num; j++) { if (j > h - i && j < h + i) printf ("%c", '*'); else printf (" "); } printf ("\n"); } break; case 'a': for (i = 1; i <= num; i++) { for (j = 1; j <= h; j++) { if (j > h - i && j > i - h) printf ("%c", '*'); else printf (" "); } printf ("\n"); } break; case 's': for (i = 1; i <= h; i++) { for (j = 1; j <= num; j++) { if (j >= i && j <= num - i + 1) printf ("%c", '*'); else printf (" "); } printf ("\n"); } break; case 'd': for (i = 1; i <= num; i++) { for (j = 1; j <= h; j++) { if (j <= i && j <= 2 * h - i) printf ("%c", '*'); else printf (" "); } printf ("\n"); } break; default: printf ("Error! \n"); } system ("pause"); return 0; }
下面给出几组输出样例:
1 2 3 4 5 6 7 请输入塔底长度和塔尖方向(w/a/s/d),使用空格分隔开:11 w * *** ***** ******* ********* ***********
1 2 3 4 5 6 7 8 9 10 请输入塔底长度和塔尖方向(w/a/s/d),使用空格分隔开:9 a * ** *** **** ***** **** *** ** *
1 2 3 4 5 6 7 8 请输入塔底长度和塔尖方向(w/a/s/d),使用空格分隔开:13 s ************* *********** ********* ******* ***** *** *
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 请输入塔底长度和塔尖方向(w/a/s/d),使用空格分隔开:17 d * ** *** **** ***** ****** ******* ******** ********* ******** ******* ****** ***** **** *** ** *
用Python 3.6实现 在用Python来编写的时候,我从sys库中导入了stdout方法。在Python中,sys.stdout是一个文件对象,它对应解释器的标准输出流。此外,在Python中,文件对象sys.stdin和sys.stderr分别对应解释器的标准输入流和标准出错流。在此不再赘述,如果感兴趣的话可以自行查阅资料了解。 使用Python 3.6编写的程序源代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 from sys import stdout num = int(input('请输入金字塔塔底长度:')) direction = input('请输入金字塔塔尖方向(w/a/s/d):') h = (num + 1) // 2 if(direction == 'w'): for i in range(1,h + 1): for j in range(1,num + 1): if((j > h - i) and (j < h + i)): stdout.write('*') else: stdout.write(' ') stdout.write('\n') elif(direction == 'a'): for i in range(1,num + 1): for j in range(1,h + 1): if((j > h - i) and (j > i - h)): stdout.write('*') else: stdout.write(' ') stdout.write('\n') elif(direction == 's'): for i in range(1,h + 1): for j in range(1,num + 1): if((j >= i) and (j <= num - i + 1)): stdout.write('*') else: stdout.write(' ') stdout.write('\n') elif(direction == 'd'): for i in range(1,num + 1): for j in range(1,h + 1): if((j <= i) and (j <= 2 * h - i)): stdout.write('*') else: stdout.write(' ') stdout.write('\n') else: print('Error! ')
由于Python程序的输出结果与上面的C程序的输出结果相似,下面只给出一组输出样例:
1 2 3 4 5 6 7 8 9 请输入金字塔塔底长度:7 请输入金字塔塔尖方向(w/a/s/d):a * ** *** **** *** ** *
写在最后 以上就是我对于金字塔图形这个经典编程练习的一些想法。输出金字塔图形的编程方法不唯一,欢迎与我进行交流。 我的邮箱:1398635912@qq.com