主题:[讨论]打印图形找不到规律,谁帮我!
zoa
[专家分:0] 发布于 2006-03-30 11:02:00
*
**
***
*****
*******
第一行1个,第二行2个,第三行3个,第四行5个,第五行7个.
有什么规律,我怎么就是看不出来规律呢,阿阿阿阿阿![em10]
回复列表 (共24个回复)
11 楼
小米123 [专家分:0] 发布于 2006-05-21 21:28:00
看看这个吧,或许对你有用的.
QB图形打印新方法
打印规则图案程序设计的新方法
曾棕根 [1]
(浙江师范大学10#,浙江 金华 321004)
摘 要:本文深入研究了规则图案的特征,发现了一种通过编制图案属性表来数字化规则图案的简便的程序设计方法。最后还考察了规则图案的花色和无级缩放。
关键词:程序设计;规则图案;多重循环;QBasic语言
规则图案熔直观性与美观性于一体,它使学生能够深入理解多重循环的工作原理,对提高学生编程兴趣和培养编程思维有独特作用,极具学习与训练价值。所以,在计算机高级语言教学中占有重要地位。遗憾的是,多年来,它的编程方法一直被忽视,停留在经验层次上。所以,历来为教学的一大难点。笔者经过多年的教学实践,在全面深入研究了规则图案的内在规律后,探索出了规则图案编程的一条通用方法。
一、图案的两个基本属性:位置和个数
从程序设计的角度上讲,任何一个平面图案,它的性质都由位置和个数这两个基本要素决定的。位置,指该图案每行在屏幕上打印的起始列号(字符屏幕一般是1~80列)。个数,指该图案每行有多少个字符。以图-1为例,此图案由三行组成,如果此图案最左边打印在屏幕第一列的话,我们就有以下的图案属性表(表-1):
二、规则图案的奥秘:等差数列
我这里将平面图案分为两类:规则图案和不规则图案。规则图案之所以很美观,是因为图案本身的两个基本属性—位置和个数为等差数列。通过观察表-1,很显然,位置3、2、1和个数1、3、5都是等差数列。研究发现,规则图案就是位置和个数分别为一等差数列的图案。
三、规则图案两个基本属性的统一途径:行号*
规则图案的两个基本属性之间是彼此孤立的。但若把行号考虑进来,三者就统一为一个有机整体。对于上下对称和上下不对称的规则图形,行号有不同的形式。研究发现,引进数学中的纵坐标系可以将这两种图形有机统一。图-2描述的是一个上下不对称的规则图案,从上到下的行号为3、2、1、0;图-3描述的是一个上下对称的图案,从上到下行号分别为2、1、0、-1、-2。这里要注意,纵坐标的原点应位于图案上下对称行上。上下不对称的图形(如图-2),原点位于图案的最底行上。
接下来我们通过图案属性表来观察行号、位置、个数三者是如何构成一个有机整体的。图-2的图案属性表表-2和图-3的图案属性表表-3中很容易发现,图案每行中行号、位置、个数三者的绝对值之和等于一常数。对于表-2,这个常数是8;对于表-3,这个常数是6。常数的变化,反映了图案行数的多寡。
值得注意的是,三者之间的有机关系,不局限于以上的规律,它是随规则图案的变化而变化的。图-4是,三者之间的关系就不同了。从表-4我们可以发现,每行行号的绝对值加1等于位置;而每行的行号的绝对值加个数的绝对值之和为一常数4,或者是每行位置的绝对值加每行个数的绝对值之和也为一常数5。
虽然三者之间的关系是变化的,但对于规则图案而言,三者之间的有机关系是一定存在的,而且也很容易找出。
四、规则图案的程序实现:双层循环
双层循环“外循环变一次,内循环变若干次”的工作原理,恰好符合规则图案程序设计要求。行号变化通过外循环变量i来实现;而每行上打印字符个数通过内循环j来控制。仿佛双层循环就是为规则图案而设计的。编程中要注意的一点是,行号用i变量表示,而位置和个数都应是只含i一个变量的表达式。表-5中,行号用i表示;由于每行行号的绝对值加1等于位置,所以,位置的表达式应为ABS(i)+1;由于每行的行号、位置、个数绝对值之和为6,所以,位置=6-行号-位置=6-ABS(i)-(ABS(i)+1)=5-2*ABS(i)。
有了表-5这个图案属性表,我们很容易将程序编制出来。这里采用Qbasic语言来描述,程序如下:
For i=2 to –2 Step –1 ‘行号
Print Tab(ABS(i)+1); ‘位置
For j=1 to 5-2*ABS(i) ‘个数
Print “*”;
Next j
Print ‘换行
Next i
五、考察花色变化:同底花色、包围花色、交替花色、动态花色
规则图案的花色常见的有同底花色、包围花色、交替花色、动态花色四类,控制花色是内循环的事情。
(1)同底花色:构成图案的字符相同。图1~图5都属于这类。
(2)包围花色:这种花色由两种字符构成。外围是一种字符,内部是另一种字符。如图-6。在内循环中只要控制每行一头一尾打印“*”,中间部分打印“S”。
If j=1 OR j=5-2*ABS(i) Then Print “S “;Else Print “*”;
包围花色中有一种特例,就是如图-7的花色。空心图案属于包围花色。内部的空心应看成是由若干空格字符组成。图-7中,只要将图-6的Print “S”这部分换成Print “ “就可以了。
(3)交替花色:图案每行由两种字符奇偶交替而成,如图-8。内循环只要控制j的奇偶位置就可以了。每行的奇位置打印“*”,偶位置打印“S”。
If j mod 2<>0 Then Print “*”;Else Print “S”;
(4)动态花色:花色由一个字符串生成,每一行的构成规律相同。如图-9。这种花色实际上由“9876”这个字符串按规律提取生成的。每行从第一个字符到中间那个字符是顺序从“9876”中依次提取字符生成的,而超过中间的字符则逆序从“9876”中提取生成的。设每行中间位置为m,那么当j<=m时,提取方法为Mid$(“9876”,j,1);当j>m时,提取方法为Mid$(“9876”,2*m-j,1)。程序如下:
For i=3 to –3 Step –1
Print Tab(ABS(i)+1);
m=(8-2*ABS(i))/2
For j=1 to 7-2*ABS(i)
If j<=m Then
Print Mid$(“9876”,j,1);
Else
Print Mid$(“9876”,2*m-j,1);
End if
Next j
Print
Next i
六、考察大小变化:无级缩放
规则图案也可以无级缩放。比如,当变量P=3时,呈现的图案为图-10状态,上下都三行,共七行。当P=2时,图案上下都为2行,共5行,图案呈现为图-11状态。当P=1时,图案上下都为1行,共3行,图案呈现为图-12状态。总之,P是任意值,随着P值的变化,图案呈现无级缩放运动。对于图-10,很容易得出,图案的总行数为2*P+1,因此图案的行号i是从P变到-P;而每行打印位置还是ABS(i)+1;每行的行号、位置、个数之和为2*P+2,故程序为:
Input p
For i=p to –p Step –1
Print Tab(ABS(i)+1);
For j=1 to 2*p+1-2*ABS(i)
Print “*”;
Next j
Print
Next i
七、结束语
打印规则图案的程序设计分为三步:绘纵坐标系、编制图案属性表、使用双重循环编程。关键是绘出图案属性表,找出行号、位置、个数之间的关系,行号用i表示,位置和个数都是关于i的一个表达式,对于任意一个规则图案,三者间关系是一定存在的,且是变化的,但都很容易找出来。程序在结构上是完全相同的,使用双重循环,外循环控制形状,内循环控制花色。这样,打印规则图案的程序设计已变得十分简单。
本研究只限于由字符(或字符型)构成的图案。对于由数字(或数值型)生成的图案不适用于本方法。
12 楼
falkner [专家分:90] 发布于 2006-05-22 19:41:00
这题没有规律所以我用了两次双循环
FOR i = 1 TO 3
PRINT TAB(i);
FOR j = 1 TO i
PRINT "*";
NEXT j
PRINT
NEXT i
FOR i = 4 TO 5
PRINT TAB(i);
FOR j = 3 TO 2 * i - 1
PRINT "*";
NEXT j
PRINT
NEXT i
第一次回复看错题目了,这次在看看是不是对了。
13 楼
chenhonghong [专家分:70] 发布于 2006-05-28 15:50:00
应该没有规律的吧
先打前面三行再打后面两行吧
14 楼
JRX [专家分:180] 发布于 2006-06-10 11:00:00
*
**
***
*****
*******
恩
我觉得是应该分两次打(前三行,后两行)
并不是所有图形都能整体有规律的~
15 楼
老大徒伤悲 [专家分:29120] 发布于 2006-06-10 21:03:00
我认为,这个问题,应该这样解决:
声明一个数组,使用read-data语句,把每行星号的个数的如数组
然后,使用数组控制输出。
写程序,达到目的是一个方面,另一方面,就是通用性,三一方面就是效率(包括内存占用和cpu占用)
至于,一个数列的规律,实在不好找,就不必找。至少在编写程序上是这样。如果通过及其复杂的计算得到数列,占用cpu就会比较大,是不合算的
16 楼
qb爱好人 [专家分:50] 发布于 2006-06-23 20:39:00
我找到规律啦!
k=1
for i=1 to 5
s=s+1
if s mod 2=0 then k=k+1
print tab(i);
for j=1 to k
print"*";
next j
next i
end
17 楼
qb爱好人 [专家分:50] 发布于 2006-06-23 20:43:00
s=-2
for i=1 to 5
s=s+1
if s mod 2=0 then k=k+1
print tab(i)
for j=1 to i+k
print "*";
next j
next i
end
18 楼
qb爱好人 [专家分:50] 发布于 2006-06-23 20:45:00
s=-2
for i=1 to 5
s=s+1
if s mod 2=0 and s>0 then k=k+1
print tab(i)
for j=1 to i+k
print "*";
next j
next i
end
19 楼
xiaophai [专家分:20] 发布于 2006-06-30 15:14:00
苯.每一行都是前面两行的"*"个数的和.
20 楼
xiaophai [专家分:20] 发布于 2006-06-30 15:15:00
失误.看错了.
我来回复