题外话1:该文之前无故丢失,找不回来了,无奈补充。
友情提示各位博友,继续支持chinaunix,这里的学习气氛还是很好的,但是一定要注意备档,尤其是重要的博文。
题外话2:这里是张老师对计算机编程的一个大串讲,初学者,不管是不是搞嵌入式的,都非常值得看。对张老师勇于开放的精神很钦佩。还有aka,还是那只大雁(涅尔什?),一直都很给力,对国内普及真正的计算机技术贡献卓越。
==================================================================================
1、问题
来自的练习题。
编写函数
diamond
打印一个菱形。如果调用
diamond(3, '*')
则打印:
*
* * *
*
如果调用diamond(5, '+')
则打印:
+
+ + +
+ + + + +
+ + +
+
如果用偶数做参数则打印错误提示。
2、分析
以diamond(5, '*')为例,如上图,将打印的图案放置到坐标系中,中心和坐标原点重合,很直观看出要求打印可见符号的区域在4条直线组成的菱形内,给定坐标(x,y)很容易判断这个点是不是在这个菱形内,如果在之内就打印可见字符'*',不在之内就打印不可见的字符,如tab。
4条直线的方程式分别是:假定t=(n-1)/2
①y=x+t
②y=-x+t
③y=x-t
④y=-x-t
根据基本的数学知识,在菱形之内的点,分别要求:
①y<=x+t
②y<=-x+t
③y>=x-t
④y>=-x-t
3、代码
#include <stdio.h>
void diamond(int n,char c) { if(!(n%2)) { printf("cannot print the diamond,wrong number:%d\n",n); return; } int x,y; int t=(n-1)/2; for(y=t;y>=-t;y--) { for(x=-t;x<=t;x++) if((y<=x+t)&&(y<=-x+t)&&(y>=-x-t)&&(y>=x-t)) printf("%c\t",c); else printf("\t"); printf("\n"); } }
int main() { diamond(7,'*'); return 0; }
|
4、代码改进
(1)当y在[0,t]时,不用考虑直线③和④造成的条件;
(2)同上理,当y在[-t,0]时,不用考虑直线①和②造成的条件;
(3)当x在[-t,0]时,不用考虑直线②和③造成的条件;
(4)同上理,当x在[-t,0]时,不用考虑直线①和④造成的条件。
综合,只需要
第二象限:判断y<=x+t
第一象限:判断y<=-x+t,且不用打印不可见字符
第三象限:判断y>=-x-t
第四象限:判断y>=x-t,且不用打印不可见字符
这样,将判断条件执行次数减少一半。
#include <stdio.h>
void diamond(int n,char c) { if(!(n%2)) { printf("cannot print the diamond,wrong number:%d\n",n); return; } int x,y; int t=(n-1)/2; for(y=t;y>=0;y--) { for(x=-t;x<=0;x++) //第二象限 if(y<=x+t) printf("%c\t",c); else printf("\t"); for(x=1;x<=t;x++) //第一象限 if(y<=-x+t) printf("%c\t",c); //else //第一象限的不可见字符不用打 //printf("\t"); printf("\n"); } for(y=-1;y>=-t;y--) { for(x=-t;x<=0;x++) //第三象限 if(y>=-x-t) printf("%c\t",c); else printf("\t"); for(x=1;x<=t;x++) //第四象限 if(y>=x-t) printf("%c\t",c); //else //第四象限的不可见字符不用打 //printf("\t"); printf("\n"); }
}
int main() { diamond(7,'*'); return 0; }
|
阅读(595) | 评论(0) | 转发(0) |