《菱形打印程序》由会员分享,可在线阅读,更多相关《菱形打印程序(4页珍藏版)》请在金锄头文库上搜索。
1、菱形打印程序一一谈如何学习算法菱形打印很多人,打印菱形在控制台的思路是,把菱形上下拆分,分两段很接近的代码来打印, 其实这样代码很不好看,并且不好阅读我们知道,要打印的图案是这种:*“ “ “ “ “*满足上下对称,左右对称,那么,你能不能也弄一个二重循环,同样是对称的? 很简单,首先我们要抛开习惯性思维,for循环不一定要在0开始或者0结束 我们可以让循环从-c到c,这样不就轻松产生一个对称的吗?(只要取个绝对值) 我们把菱形的中心看成是坐标0,0,那么,会输出星号的坐标,是1x1 + lyl = c的点由此可得#include #define IABS(x) ( (x) = 0 ? (x)
2、 : -(x) ) /定义一个计算绝对值的宏void print(int size) / size是这个菱形的半径,直径会是size * 2 + 1int x, y;for (y = -size; y = size; y+)for (x = -size; x = size; x+)if ( IABS(x) + IABS(y) = size ) /x 和 y 各自的绝对值的和,即 lxl + lyl = size putchar(*);elseputchar();putchar(n);int main()print(5); /输出一个半径为5的菱形getchar();return 0;如果我需要
3、得到空心菱形呢?非常非常简单,因为菱形边界上的点,满足的是刘+ lyl = c 所以,我们只要把那个if里的小于等于号,改成双等于号=就可以了再类似地,如果我不要*号,我要最外层是字母A,然后里一层是B这样呢?即:AABAABCBAABAA那么,我们只要在putchar那里做一个字符计算:void print(int size) / size是这个菱形的半径,直径会是size * 2 + 1int x, y;for (y = -size; y = size; y+)for (x = -size; x = size; x+)if ( IABS(x) + IABS(y) = size ) /x 和
4、 y 各自的绝对值的和,即 lxl + lyl size,所以前面输出了三个,然而由于|x|渐渐减小, 之后输出了一个*,由于|x|又渐渐增大,又输出了三个,这样就巧妙地完成了左右的 对称。又由于下一次循环|y|比这次循环小1,所以就“更容易”输出*,由于|y|也有对称的特性, 所以完成了上下的对称。至此,我们大概就对为什么可以上下左右对称有了一个感性的认识,不过恐怕更多的是对这 些代码的惊叹:为什么这样写就能巧妙地做到这些? IABS(x) + IABS(y) = size这个表达 式也太神奇了!其实我们上来看程序的运行过程,只是为了从运行过程中试着找到入口去探 索这个算法的本质是什么,这是
5、一个从现象到本质的过程,而不能被现象吓到了。我们把菱形的中心看成是坐标0,0,那么,会输出星号的坐标,是|x| + |y| = c的点 那么程序的原理实际上就是通过枚举(x,y), |x| = size, |y| = size, x, y EZ中的 点(即下图中红色部分,包括边界),再通过一个式子来确认合法点,如果合法,就输出* ,反之输出:size-size那么我们又有疑问了,为什么是|x| + |y| = c?我们来证明一下上面右上角的红色三角区域(包括边界)的所有点(x,y) (x,yEN),x+y =size (自己先试试看):通过观察,我们可以发现y的取值范围随着x在改变,至于“怎么
6、改变”则与size有关, 那么我们可以想一下,如果我们把其中的y用size和x表示,这个不等式不就容易得证了 吗?那么我们可以得知yE0, size-x (x尹size),取两边分别讨论,当y=0时,x+y=x=size, 当 y=size-x 时,x+y=x+size- x=size, 当 yE(0, size-x) (x尹size)时,x+ysize。综 上所述,x+y=size,证毕。其实即使你不会证明,也可以当作公式默认下来,这都无关紧要。于是我们就能自己写出|x| + |y| = c这个式子了,也就知道了这个算法的本质,现在一 切都掌握在我们手中,甚至我们可以对原程序做一点改动:由于
7、是枚举(x,y)(x,y), |x| = size, |y| = size, x, y EZ,而且有绝对值的对称 做保障,那么无论x、y谁在外面只要全枚举到就行了,所以也可以把x放在外层循环:for (x = -size; x = size; x+)for (y = -size; y = size; y+)if (IABS(x) + IABS(y) = size) /x 和 y 各自的绝对值的和,即 |x| + | y| = size putchar(*);elseputchar();putchar(,n,);观察原程序的输出,我们可以发现由于对称的缘故,程序输出的右侧多输出了我们看不见的 空格,我们也可以不输出它:if (IABS(x) + IABS(y) = size ) /x 和 y 各自的绝对值的和,即 |x| + | y| = size putchar(,*,);else if (x 0)putchar(,);elsebreak;虽然上述改动没有太大意义,但是说明了如果我们掌握了算法的本质,我们就掌握了全局, 那么就可以进行任何改动的道理。