【例 326】Fibonacci(斐波那契)序列的前两项是 0 和 1,且每个后继项是前两项的和。
因此 Fibonacci 序列为:0,1,1,2,3,5,8,13,21,34,…编写程序输出项的值不大于 1000 的 Fibonacci 序列。
(1)建立应用程序用户界面。在一个新窗体中添加一个文本框 Text1、一个标签 Label1、
两个命令按钮 Command1 和 Command2,如图 324(a)所示。其中文本框 Text1 的 MultiLine 属性设置为 True(显示多行文本),ScrollBars 属性设置为 2-Vertical(显示垂直滚动条) 。
(2)编写 Command1 和 Command2 的单击事件代码,执行结果如图 324(b)所示。
Private Sub Command1_Click()
Dim i1 As Integer, i2 As Integer, i3 As Integer, n As Integer i1 = 0: i2 = 1: n = 1
p = "第 1 项=" & i1 Do While i2 <= 1000
n = n + 1
p = p & Chr(13)& Chr(10)& "第" & n & "项=" & i2 i3 = i1 + i2
i1 = i2 ' 得到新的 i1
i2 = i3 ' 得到新的 i2
Loop
Text1.Text = p
Label1.Caption = "Fibonacci(斐波那契)序列:" & Chr(13)& _
"其值不大于 1000 的共有" & n & "项"
End Sub
Private Sub Command2_Click()
Unload Me End Sub
(a) (b)
图 324 Fibonacci 序列
说明:每执行一次循环体,由前两项求出第 3 项,即 i3=i1+i2,然后把原来的第 2 项赋给 i1,即 i1=i2,再将新求出的第 3 项赋给 i2,即 i2=i3,只要 i2≤1000,就不断重复执行循环体,
并将每项的值累计到变量 p 中,用变量存储输出项的个数,退出循环后再一次将累计到变量 p 中的所有项的值显示在文本框中。函数 Chr(13)表示回车,Chr(10)表示换行。
【例 327】输入两个正整数,求它们的最大公约数,程序运行界面如图 325 所示。
图 325 运行结果
求两个正整数的最大公约数可以采用“辗转相除法” ,如下:
(1)以大数 x 作被除数,小数 y 作除数,相除后的余数为 r。
(2)若 r≠0,则 x←y,y←r,继续 x 与 y 相除得到新的 r,若仍有 r≠0,则重复此过程,
直到 r=0 为止。
(3)最后的除数 y 就是最大公约数。
Private Sub Command1_Click() x = Val(Text1.Text)
y = Val(Text2.Text) If x * y = 0 Then
MsgBox "两个数都不能为 0!", "错误!"
Exit Sub End If
If x < y Then t = x: x = y: y = t Do
r = x Mod y
If r = 0 Then Exit Do
x = y: y = r Loop
Label3.Caption = "两数的最大公约数是:" & Trim(Str(y)) End Sub
此例中利用了 Exit Do 语句来退出 Do…Loop 循环语句。
【例 328】编写程序:为小学生随机出题,进行四则运算训练。要求自动产生 10 以内的 随机整数,四种运算操作符也由随机函数产生。
(1)建立应用程序用户界面。在窗体中添加一个标签 Label1(显示题目) 、一个文本框 Text1(输入计算结果)、一个命令按钮 Command1(计分)和一个列表框 List1(显示做题的对 错),如图 326(a)所示。
(a) (b)
图 326 四则运算
(2)编写程序代码。
Option Explicit '在通用段强制变量声明
Dim Num1%, Num2% ' 两个操作数
Dim SExp$ ' 存放产生的算术表达式
Dim Result! ' 计算机计算结果
Dim NOk%, NError% ' 统计计算正确与错误数
编写窗体的 Load 事件,随机产生两个操作数和运算符号:
Private Sub Form_Load() ' 通过产生随机数生成表达式 Dim NOp%, Op As String * 1, t% ' NOp 操作符代码
Randomize '初始化随机数生成器
Num1 = Int(10 * Rnd + 1) '产生 1~10 之间的操作数 1 Num2 = Int(10 * Rnd + 1) '产生 1~10 之间的操作数 2 NOp = Int(4 * Rnd + 1) '产生 1~4 之间的操作代码 Select Case NOp
Case 1 '当 NOp=1 时,加法运算
Op = "+"
Result = Num1 + Num2 'Result 存放正确结果 Case 2
Labell
Op = "-"
Do While Num1 Mod Num2 <> 0 '若不能整除,则产生下一组数 Num1 = Int(10 * Rnd + 1) '再次产生 1~10 之间的操作数 1 Num2 = Int(10 * Rnd + 1) '再次产生 1~10 之间的操作数 2 Loop
Result = Num1/Num2 End Select
SExp = Num1 & Op & Num2 & "="
Label1 = SExp End Sub
编写 Text1 的 KeyPress 事件,判断正确与否:
Private Sub Text1_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then
If Val(Text1) = Result Then '检查计算是否正确
List1.AddItem SExp & Text1 & Space(3) & "√ " '计算正确 NOk = NOk + 1
Else
List1.AddItem SExp & Text1 & Space(3) & "×" '计算错误 NError = NError + 1
End If
Text1 = "" '下一个表达式生成
Text1.SetFocus Form_Load End If End Sub
程序运行结果如图 326(b)所示,请有兴趣的读者修改程序,美化界面,编写出更适合 小学生使用的四则运算应用程序。
【例 329】百元买百鸡问题。假设小鸡每只 5 角,公鸡每只 2 元,母鸡每只 3 元。现有 100 元钱要求买 100 只鸡,编写程序找出所有可能购买的方案,程序执行结果如图 327 所示。
分析:根据题意,设母鸡有 x 只,公鸡有 y 只,小鸡有 z 只,列出方程:
Print "母鸡", "公鸡", "小鸡"
For x = 0 To 33 '母鸡可能买的数量范围 For y = 0 To 50 '公鸡可能买的数量范围 For z = 0 To 100 '小鸡可能买的数量范围
n = n + 1 '计数,求出循环的次数
If 3 * x + 2 * y + 0.5 * z = 100 And x + y + z = 100 Then Print x, y, z
End If Next z Next y Next x
Print "共计算了", n, "次"
End Sub
图 327 程序执行结果 方法二:用二重循环。
Private Sub Command2_Click() Dim x%, y%, z%, n%
'Cls Print
Form29.ForeColor = RGB(0, 0, 255) Print "方法二:双循环"
n = 0
Print "母鸡", "公鸡", "小鸡"
For x = 0 To 33 For y = 0 To 50
z = 100 x – y '小鸡的数量 n = n + 1
If 3 * x + 2 * y + 0.5 * z = 100 Then Print x, y, z
End If Next y Next x
Print "共计算了", n, "次"
End Sub
以上算法称为“穷举法”或“枚举法” ,即利用计算机速度快的特点将可能出现的情况用 循环结构逐一罗列,判断是否满足条件。