本帖最后由 IT-capfer 于 2015-11-20 00:35 编辑
有这么一个命题:请打印一个边长为5顶角为60度的空心菱形,如图“空心菱形”。
根据老师讲过的思路,我们通常会选择将这个空心菱形拆分为一个正三角和一个倒三角,使用两个for循环嵌套,并且还要重复使用一次,代码繁冗,操作复杂。这个解决方案我就不做了。我今天要讲的是如我标题所示,我想采用一种更简单直接而且容易接受容易进一步发挥计算机的特点的方法。
观察图案,在我眼里这既是一个星星图案,其实也是四条线段!还有我们需要定义的整型变量(int a和int b),有行有列的,这不就是坐标值吗?我编译后执行的图案完全可以看做是一个坐标象限呀。既然如此,这四条线段,我们就能求出它相应的数学函数表达式。
第一步,列坐标。A(4,0);B(0,4);C(4,8);D(8,4)
看坐标该图案位于第一象限,直观感觉上和我们的坐标图不一样,所以不能想当然的根据直线走向决定直线的斜率,应该通过数据把直线求出来。
第二步,求直线。回到我们初中时代的数学,直线的函数表达式是:y=kx+b.带入四个点决定的四条边线。则:
直线AB:4k+b=0;b=4.=====>>k=-1;b=4.即y=-x+4;
直线AD:4k+b=0;8k+b=4.===>>k=1;b=-4.即y=x-4;
直线BC:b=4;4k+b=8.======>>k=1;b=4即y=x+4;
直线CD:4k+b=8;8k+b=4.=>>k=-1;b=12即y=-x+12.
第三步,写代码。我们定义的两个整型变量a和b,分别表示行循环和列循环,即函数中的x和y。而空性菱形正是由这四条直线相交而成,所以只需确定x和y的范围,通过if函数定下四条直线的条件,就可以输出打印了。
#include<stdio.h>
int main(){
for (int a=0; a<9; a++) {
for (int b=0; b<9; b++) {
if (b==-a+4||b==a-4||b==a+4||b==-a+12) {
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
return 0;
}
通过数学几何函数,我们非常容易接受定义的整型变量应该要从0开始,因为从0开始就是我们的坐标原点。要是不进入这一层来理解,我以前总觉得,int a和b,从1开始不是更好吗?呵呵。
引申一:
如果题目改一下,说要打印一个实心的空心菱形呢?
我们知道四条直线相交部分即是我们所要求的实心区域。这一点在数学上非常容易表达,只需将“=”改为“<=”或者“>=”即可。
到底是大于还是小于呢?这不同于第一象限,凭感觉容易出错,我们不妨代入该菱形的中心坐标(5,5),比较等式两边大小即可。很容易得到:
b>=-a+4;b>=a-4;b<=a+4;b<=-a+12即是所求。
所以得到的代码是:
#include<stdio.h>
int main(){
for (int a=0; a<9; a++) {
for (int b=0; b<9; b++) {
if (b>=4-a&&b>=a-4&&b<=a+4&&b<=12-a) {
printf("*");
}else
printf(" ");
}
printf("\n");
}
return 0;
}
真的相当简洁!
引申二:
我们听过上面两个事例验证了计算机打印其实就是数学的函数原理,既然如此,那么数学的函数图像都可以通过一个公式设定起范围就可以打印出来了,就再也不用我们费心费力去构思编程了。比如圆形:(x-a)*(x-a)+(y-b)*(y-b)=R*R;抛物线:y=k*x*x-b……那些复杂的图像也太容易了哦。同学们去试试吧。唯一需要注意的是,我们编译后的输出更多的像是像素点的打印,一个点一个点构成的直线和曲线,如果数值小,很可能不精确。只有像素点足够多的时候图案会越真实。
北京IOS1111基础班
|
|