前言
打印菱形这道题对于初学编程者来说简直是噩梦,曾经我就是栽在这上面的,后来编程编多了之后对打印菱形也觉得不再那么难了,去年在公众号写了一篇推送是关于打印菱形的,觉得对一些师弟师妹还是有所帮助的,今天就把这道题分享出来。
以下是我遇到的各种各样的菱形:
普通菱形,输入n,输出n行n列的菱形
难度系数:♥
n行空心菱形,输入n,输出n行空心菱形
难度系数:♥♥
n行挖空菱形,输入n,输出n行n列空格菱形
难度系数:♥♥♥
n行数字菱形,输入n,输入n行数字从外到内递增的数字菱形
难度系数:♥♥♥♥
有边框空心菱形,输入n,输出n行带有边框的空心菱形
难度系数:♥♥♥♥♥
首先我们要明确这是一个随着n的大小改变的菱形,所以我们肯定要用到循环,并且循环的次数与n有关。如果题目要求是输出n行,那我们的循环就是0(n-1)或者1n;如果要求是输出(2n+1)行,那我们的循环就0-2n或者1~(2n+1)即可。(后面以输出n行为例分析)
第一个是普通的实心菱形,循环n行大家都懂,问题就在列要怎样循环。难道是看出来的吗?不错,我就是通过看得出来的循环次数。具体怎么看呢?
根据图直接看有点难度,所以我们根据各行数据来看
我们需要将整个菱形分成四块来考虑,从上到下空格的个数先从n/2递减到0后递增到n/2,而行循环因子i又从0递增到n,故自然可联想到用i与n/2来表示空格个数。因为空格个数是非负数,所以我们引进绝对值|n/2-i|表示空格个数。打完空格之后,我们就要正式用 ' * '打印菱形了。通过观察我们发现 * 号的个数为奇数,并且变化规律跟空格正好相反,所以号个数即是-2*(空格个数)+1+C(常数)=-2*(空格个数)+C(常数),通过观察我们发现这个常数C正好是n/2。于是第一种菱形就可以顺利完成了!
第二个是空心菱形,与实心菱形相似,可看成在实心菱形上再打了一个空格菱形。由于每行的号数不多,并且可以看到号正好位于空格菱形的外围,所以我们可以将打印号放在打印空格菱形前后顺便打印,即在打印空格菱形之前打号,打印完空格菱形之后再打印号。同样,我们将相关数据列出来然后观察规律。号前空格与实习菱形一致,而我们发现n-2|n/2-i|-2的值除了首尾两行外,其他都与空格菱形的空格个数一致,而首尾两行是-1表示在该处不需打空格反而需要退一个格,但由于我们当前位置为号,而退格后依旧要打号,所以我们可以直接判断是否为第一行或最后一行,是则少打印一个号即可。
第三个是挖空菱形,该菱形是上述两个的合体,我们可以看成把一个实心菱形的各个字符替换成另一种字符,再插入一个空心菱形。所以我们把该菱形分成输出空心菱形前后号和输出空心菱形两部分。通过数据对比,我们不难发现,输出空心菱形前后号的数据与实心菱形输出号前空格个数一致,然后就是输出一个空心菱形,最后要记得在输出空心菱形之后输出空心菱形之后的号,根据对称可知,空心菱形后号个数与空心菱形前号一致。
第四个是数字菱形,该菱形的特点是数字从外到内逐层递增。我们发现该菱形中轴线数字的变化规律是先从1递增到(n+1)/2,然后再递减到1,并且每一行的数字也是从1递增到中轴线,再递减到1,因此我们要找到中轴线所在的位置(方便判断循环因子是否到达中轴线)。通过列数据我们发现中轴线所在位置(j从0开始循环)为n/2-|n/2-i|,所以在每一行中我们的数字加到“j==n/2-|n/2-i|”处时应该转成递减,所以我们引进要填充的数字k,在每一行开始时k为1,在j从0到n/2-|n/2-i|-1中,k逐次递增,在j从n/2-|n/2-i|到n-2*|n/2-i|-1中k递减。然后将打印星号改为打印数字即可。
第五个是边框空心菱形。从名字可知,该菱形由边框和空心菱形组成,我们可以将边框和空心菱形分开来考虑。第一行和最后一行为边框,可直接用从0到n-1打印号实现。左右边框在每一行的开头和结尾打印号即可实现。中间即是空心菱形的领域,基本上跟打印空心菱形一样,只是要注意被边框覆盖的地方空格和号要省略。
将打印空格和打印号分开考虑,通过数字之间的关系特点,运用循环完成菱形的打印。
由于菱形是对称的,所以绝对值是最好的数据描述工具,要巧妙地运用绝对值,将对称部分的循环用同一个带有绝对值的表达式表示出来。
值得注意的是n/2为整数除,所以不会得到小数,也不是四舍五入。
中轴线所在位置(j从0开始循环)为n/2-|n/2-i|。
//挖空菱形 for(i=0;i<n;i++){ for(j=0;j<abs(n/2-i);j++) printf("*"); printf("*"); for(j=0;j<n-2*abs(n/2-i)-2;j++) printf(" "); if(j!=0) printf("*"); for(j=0;j<abs(n/2-i);j++) printf("*"); printf("\n"); } printf("\n"); //边框菱形 for(i=0;i<n;i++){ if(i==0||i==n-1){ for(j=0;j<n;j++) printf("*"); printf("\n"); } else{ printf("*"); for(j=0;j<abs(n/2-i)-1;j++) printf(" "); if(j!=0) printf("*"); for(j=0;j<n-2*abs(n/2-i)-1;j++) printf(" "); if(j!=0) printf("*"); for(j=0;j<abs(n/2-i)-1;j++) printf(" "); if(j!=0) printf("*"); printf("\n"); } } //数字菱形 for(i=0;i<n;i++){ int k=1; for(j=0;j<abs(n/2-i);j++) printf(" "); for(j=0;j<n-2*abs(n/2-i);j++){ printf("%d",k); if(j<n/2-abs(n/2-i)) k++; else k--; } printf("\n"); } //实心菱形 for(i=0;i<n;i++){ for(j=0;j<abs(n/2-i);j++) printf(" "); for(j=0;j<n-2*abs(n/2-i);j++) printf("*"); printf("\n"); } printf("\n"); //空心菱形 for(i=0;i<n;i++){ for(j=0;j<abs(n/2-i);j++) printf(" "); printf("*"); for(j=0;j<n-2*abs(n/2-i)-2;j++) printf(" "); if(j!=0) printf("*"); printf("\n"); }
总结
到此这篇关于利用C语言打印菱形的文章就介绍到这了,更多相关C语言打印菱形内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!