在上篇文章提到如有心可以尝试着写一写空心菱形程序,然后发送给我,本不报太大希望的,没想到竟然收到了几篇,颇感意外。
但有一点让我感觉意外,该篇文章先额外补充一下。在第(1)节中,我提到由该例子引出了三个重要概念,其中第二个概念是:边界判断。给出两个数,如何完备且简洁的判断其是合理的输入,这是编程的基本功。很可惜的是,这几个例子都没有做到。结合自己多年带人的经验,这儿补充阐述一下。
输入两个数,一个是外菱形的高度(m表示),一个是内菱形的高度(n表示),有如下几个判据:
1.两个高度都应该是正整数(内菱形高度可以为0);
2.受限于屏幕的大小,菱形高度应该受限;
3.外菱形高度应该大于内菱形的高度。
以前带人的时候,拿到例程后,我喜欢先输入(,)这样的值,因为这是容易被忽略的地方,很多人郁闷的铩羽而归。
大部分人都是缺判据,也有一些人性格比较谨慎,习惯写一大堆的判断条件,如下面这种的:
if(m0n0mnm30n30){
……
}
总之,都没有抓住判断条件应该完备且简洁的基本准则,实际上该例子很简单,只要简单的分析,判断条件也就三个,如下:
1.内菱形高度大于等于0;
2.外菱形高度小于约定之(假设30);
3.外菱形高度大于内菱形高度;
写成程序示意如下:
if(n=0mnm30){
……
}
还记得第(1)节中我们约定菱形的高度是上三角形高度吗,带来的好处就是判断的简洁化,概念是为目标而服务的,不然该处的判断还需要额外的增加两条奇数判据了,简洁性也会打折扣了,呵呵,可以再回味一番。
在嵌入式产品中,最终产品的鲁棒性,很多时候就是表现在这样一点一滴的简单判据上,该处的不厌其烦,也是期望新人慢慢的融入研发团队时,能够充分意识到这一点。
◆
终于要开始输出空心菱形了,但对于刚毕业的大学生,这个例子刚上手还是有一些绕的,其思维逻辑是如何的呢。
一般人都会发现,输出空心菱形要稍微复杂一些,那么我们修改为输出菱形呢,是否简单很多,如果还嫌复杂,修改为输出三角形呢。呵呵,说白了,就是将复杂的问题去其枝叶,先简后繁的慢慢处理。
一开始的问题就简单多了,已知三角形高度m,输出三角形,如m=5,输出如下:
*
***
*****
*******
*********
为了直观,将空格也表示出来,示例如下:
----*
---***
--*****
-*******
*********
此时,结论已经很形象了,每行输出的空格从m-1递减,每行输出的*从1开始递增,循环子为m,程序示例如下:
for(i=1;i=m;i++)
{
j=m-i;
while(j--)
printf();
j=i*2-1;
while(j--)
printf(*);
printf(\n);
}
问题复杂化,考虑空心三角形,相当于里面又多了一个三角形,我们输出的时候,将其简单扣去即可,假设n=3,如下图示例:
----*
---***
--**-**
-**---**
**-----**
程序示例如下:
for(i=1;i=m;i++)
{
j=m-i;
while(j--)
printf();
j=i*2-1;
for(k=0;kj;k++)
{
if(km-n
k=j-m+n)
printf(*);
else
printf();
}
printf(\n);
}
进一步复杂化,输出完整的空心菱形,仅仅需要将上面的程序重复一下,仅仅是将其颠倒一下,且高度调整一下(减1处理,表达式更加复杂了)而已,我就不展示示例程序了,大家有兴趣的可以自己尝试一下。
◆
有些人在实现该程序的时候,一开始就是对空心菱形进行分析,最直观的分析策略就是将菱形分层了三段,上三角形,下三角形,中间的空心部分,如下图示意:
*
***
****
****
****
****
****
***
*
按照这种思路,程序示意如下:
for(i=1;i2*m;i++)
{
if(i=m-n){
star=2*i-1;
empty=m-i;
while(empty--)
printf();
while(star--)
printf(*);
}
elseif(m-niim+nj2*n){
if(j=ni=m){
num_empty=2*j-1;
empty=m-i;
}
else{
num_empty=2*(2*n-1-(j-1))-1;
empty=i-m;
}
num_star=star=m-n;
while(empty--)
printf();
while(star--)
printf(*);
while(num_empty--)
printf();
while(num_star--)
printf(*);
j++;
}else{
star=2*(2*m-1-(i-1))-1;
empty=(2*m-1-star)/2;
while(empty--)
printf();
while(star--)
printf(*);
}
printf(\n);
}
不管如何,至此,这个例程就算完成了,但大家有没有发现上面这些程序都谈不上优雅啊,其中各种m和n的表达式,一段时间以后看,基本同乱麻差不多了,试想,如果这是产品的程序,让后来人如何阅读并维护。
◆
通过