注:本人CS系大学生。C之前有接触过但基本忘得差不多了,目前在重新学习C。
今天看到个题目,说是用C的for循环语句打印一个图示的实心菱形:
对别人来说很简单,但对于我这个刚刚认识完循环语句的新手来说很难。光是想就想了很久很久,终于想出来了。写这篇博客一是将自己的思路存档供日后查看,二是把我的思路分享给大家,希望对同样是学习路上的大家有所帮助。完整源码在文末。
题目要求打印的效果是菱形,但实际上我们可以构造一个7*7的正方形。只不过菱形的组成部分用星号来表示,而空白部分则用表示。这里以一个7*7的菱形为例:
空白效果:
实际效果:
那第一步思路就清晰地出来了,使用两个for语句来生成空白的正方形:
#includeint main() { int coloum = 7; // 定义菱形的宽(高)度 // i代表行, j代表列 for (int i = 0;i <= coloum;i++) { for (int j = 0;j <= coloum;j++) { } } }
之后我们先让它们生成只有空格的7x7的正方形。为了方便识别,这里空格用"?"代替。
#includeint main() { int coloum = 7; // 定义菱形的宽(高)度 // i代表行, j代表列 for (int i = 0;i <= coloum;i++) { printf("? "); for (int j = 0;j <= coloum;j++) { printf("? "); } printf("n"); // 别忘了换行噢 } }
生成的效果如下:
成功生成正方形之后,接下来思考如何在这个正方形之中来画出所需要的实心菱形。
再来观察一下应该得到的图形的样子:
想要在这个正方形内画出菱形,就要确认组成菱形的每一个星号所在的位置。
你会发现每一行至少都会有一个星号,而且最中间的列一定会有一个星号。 那么其余的星号也一定与这个中间列的星号有关。我们将这个中间列的星号定义为int mid = coloum/2+1,即中位数。
(注意:在C中对整数进行除运算时会向下取整。想要获得之中位数的话,需要在原来的值上+1)
从第4行看起,第1、第2、第3、第4行的星号数量都是呈金字塔状递增的;而第5、第6、第7行的星号数量呈金字塔状递减。那么说明在不同行之间,星号的变化规律并不完全一样。所以我们需要把行数分割为上半部分和下半部分,也就是说,我们要对i的取值分别讨论。
#includeint main() { int coloum = 7; // 定义菱形的宽(高)度 int mid = coloum / 2 + 1; // 获取菱形行(列)的中位数,也就是最中间行(或列)的位置 // i代表行, j代表列 for (int i = 0;i <= coloum;i++) { if (i <= mid) { // 当行数处于上半区(包括最中间的行)时 for (int j = 0;j <= coloum;j++) { printf("? "); } }else if (i > mid) { // 当行数处于下半区时 for (int j = 0;j <= coloum;j++) { printf("? "); } } printf("n"); // 别忘了换行噢 } }
我们将上半区单独分出来仔细观察:
在第一行中,星星所处的位置只有4。
在第二行中,星星所处的位置为3,4,5。即[3,5]这个区间。
在第三行中,星星所处的位置为2,3,4,5,6。即[2,6]这个区间。
在第四行中,星星所处的位置为1,2,3,4,5,6,7。即[1,7]这个区间。
不难发现,星星所处的位置为一个闭区间,分别为[4,4],[3,5],[2,6],[1,7]……即为4±0,4±1,4±2……
所以我们可以这样想:如果j(列数)处于这个区间内,那么输出“*”,否则输出空格。而且这些区间都是与菱形宽(高)度的中位数相关的。
即,星号的位置为一个区间。而对于上半区来说,这个区间为:[行的中位数(mid)-(当前行数-1),行的中位数(mid)+(当前行数-1)]。用代码实现便是:
for (int j = 0;j <= coloum;j++) { if (j >= mid - (i - 1) && j <= mid + (i - 1)) { printf("*"); } else printf(" "); }
执行结果如下:
(因为还没处理下半部分代码,所以那里全是问号)
接下来我们来看下半区:
在第五行中,星号所处的位置为2,3,4,5,6,即[2,6]这个区间。
在第六行中,星号所处的位置为3,4,5,即[3,5]这个区间。
在第七行中,星号所处的位置只有4。
不难发现,星号所处的位置为一个闭区间,分别为[2,6],[3,5],[4,4]。即为4±2,4±1,4±0。星号的变化顺序刚好与前3行相反,为递减关系。
对于下半区来说,星号所处的区间规律为:[mid-(总行数-当前行数),mid+(总行数-当前行数)]。用代码实现就是:
for (int j = 0;j <= coloum;j++) { if (j >= mid - (coloum - i) && j <= mid + (coloum - i)) { printf("*"); } else printf(" "); }
执行结果如下:
至此,代码已完成,可以实现题目要求的功能。可以自由改动column的值,生成任意大小的菱形。(注:coloum值必须为奇数,不然不能生成菱形)
完整源码如下:
#includeint main() { int column = 7; // 定义菱形的高度(宽度) int mid = column / 2 + 1; // 获取菱形高(宽)的中位数 printf("%dn", mid); // i是行数 j是列数 for (int i = 1;i <= column;i++) { // 对行进行循环 if (i <= mid) { // 判断行数是在上方还是下方。这里是上方的情况(包括中间一行 for (int j = 1;j <= column;j++) { // 对列进行循环 // 判断单个列的情况 // 对上半区来说: // 星星的位置为一个区间 即[行的中位数-(行数-1),行的中位数+(行数-1)] if (j >= mid - (i - 1) && j <= mid + (i - 1)) { printf("*"); // 输出星号 } else printf(" "); // 输出空格 } } else if (i > mid) { // 判断行数是否处于下方 for (int j = 1;j <= column;j++) { // 判断单个列的情况 // 对下半区来说: // 星星的位置为一个区间 即[行的中位数-(总行数-当前行数),行的中位数+(总行数-当前行数)] if (j>=mid-(column-i) && j<=mid+(column-i)) { printf("*"); // 输出星号 } else printf(" "); // 输出空格 } } printf("n"); } }
感谢你的阅读!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)