内容正文:
内蒙古自治区(计算机类)对口招生
《Visual Basic程序设计》复习讲义
模块 7 数组
考点 15 数组常用算法实例
【考纲要求】
1. 掌握常用算法实例。
【知识网络】
【知识和技能要点】
一、求最大值与最小值及其位置
1. 求最大值及其位置
在数组中找最大值,一般先用一个变量存下第一个元素作为暂定的最大值,再让循环从第二个元素开始逐个与它比较。一旦发现当前元素比暂定值更大,就把这个元素换到最大值变量中,同时用另一个变量记下它的下标。循环结束后,最大值变量与下标变量里保存的就是要找的结果。要注意初值必须取数组中的实际元素,取 0 会在元素全为负数时得到错误答案。
2. 求最小值及其位置
求最小值的思路与求最大值完全一样,只是把比较的方向反过来:当前元素小于暂定最小值时才替换,同时记下它的下标。这里同样要注意初值的选取。如果把最小值变量先置成 0,而数组元素又恰好全部是正数,那么 0 永远不会被替换,最终输出的就是一个并不在数组中的数字,因此初值也必须取第一个元素。
二、统计与平均值
1. 求和与平均值
求和时要设一个累加变量并在进入循环之前把它清零,循环中把每个元素依次加入其中。求平均值则在求和结束之后再除以元素的个数。如果题目要求的是修剪平均值,也就是去掉一个最高分和一个最低分后计算其余分数的平均值,那么就要在求和的同时用两个变量分别跟踪最高分与最低分,最后从总和里减去这两个值,再除以剩下的个数。
2. 计数与分类统计
统计满足条件的元素个数时,要设一个计数变量并在循环之前清零,循环中用"条件成立就把计数变量加 1"的方式累加。这类题目的条件常常写成元素与平均值比较,因此往往要先遍历一次数组求出平均值,再遍历第二次完成统计。如果要按分数段分类统计,可以用一个数组来保存各段的人数,用元素值整除 10 的结果作为它的下标。
三、排序
1. 冒泡排序法
冒泡排序在每一趟中把相邻的两个元素依次比较,不符合次序就互换。这样一趟走下来,最大的数就沉到了末尾,较小的数则逐步向前浮起。程序用外层循环控制趟数、内层循环控制每一趟里比较的次数,内层循环的终值要随外层循环变量递减。如果数组还带着另一列数据,例如运动员的号码,互换时必须把它一起交换,否则数据就错位了。
2. 顺序比较法与选择排序法
顺序比较法是让第 i 个元素与它后面的每一个元素逐一比较,发现更小的就立即互换。选择排序法的比较过程与它完全一致,区别只在于:发现更小的元素时先用一个变量记下它的下标而暂不互换,等内层循环结束之后再交换一次。这样每趟最多只需交换一次,交换的次数明显减少,因此效率比顺序比较法高。
四、二维数组(矩阵)的常用算法
1. 矩阵元素的输入与遍历
二维数组的元素一般用两层循环逐个访问:外层循环变量作行号,内层循环变量作列号。输入时在内层循环中把读到的数据赋给当前元素;也可以在循环中用条件语句按规律直接给元素赋值,例如生成一个 5 行 5 列的数组、让两条对角线上的元素取 1 而其余取 0——此时要判断行号是否等于列号,或者行号与列号之和是否等于行数加一。
2. 矩阵中的最大值及其位置
求矩阵中的最大数时,要用两层循环依次访问每一行每一列的元素,外层的循环变量是行号、内层的是列号。程序通常先把左上角的元素同时作为最大值与位置的初值,即令行号与列号都取 1;此后一旦发现更大的元素,就把最大值换成它,并把当前的行号与列号分别记入两个变量。循环结束后输出这两个变量,就能说明最大数位于第几行第几列。
【真题】
2022年真题|程序填空题第131题 窗体上有一文本框 Text1 和一个图片框 Picture1,在文本框中输入英文字符串后单击图片框,程序统计英文字符出现的次数,并显示在图片框上。程序代码如下,请补充完善程序代码。
Private Sub Picture1_Click()
Dim ss As String
Dim a(1 To 26) As Integer, i As Integer, k As Integer
k = Len(Text1.Text)
For i = 1 To [21]________
ss = UCase(Mid(Text1.Text, i, 1))
If ss >= "A" And ss <= [22]________ Then
[23]________ = a(Asc(ss) - 64) + 1
End If
Next i
For i = 1 To [24]________
If a(i) <> 0 Then [25]________ Chr(i + 64) & "="; a(i); " "
If i Mod 8 = 0 Then Picture1.Print
Next i
End Sub
【答案】[21] k;[22] "Z";[23] a(Asc(ss) - 64);[24] 26;[25] Picture1.Print
【解析】字符串的长度已存入变量 k,逐个取字符的循环应从 1 取到 k,故 [21] 处填 k。判断取出的字符是不是英文字母,要同时满足不小于 "A" 且不大于 "Z",故 [22] 处填 "Z"。数组 a 的每个元素存放对应字母出现的次数,Asc(ss) - 64 恰好把 A 到 Z 折算成下标 1 到 26,故 [23] 处填 a(Asc(ss) - 64)。数组共有 26 个元素,输出循环的终值是 26,故 [24] 处填 26。要把统计结果显示到图片框上,应调用图片框的 Print 方法,故 [25] 处填 Picture1.Print。
2023年真题|第131题 下列程序的功能是单击 Command1 从键盘上输入运动员的号码和成绩,然后单击 Command2,将按成绩排出名次并输出。请将程序补充完整。
Dim A(1 To 10, 1 To 2) As Single
Private Sub Command2_Click()
Dim Max As Single
For i = 10 To 2 Step -1
For k = 1 To [11]________
If A(k, 2) > A(k + 1, 2) Then
t = A(k, 2)
[12]________
A(k + 1, 2) = t
r = A(k, 1)
[13]________
A(k + 1, 1) = r
End If
Next k
Next i
End Sub
【答案】[11] i - 1;[12] A(k, 2) = A(k + 1, 2);[13] A(k, 1) = A(k + 1, 1)
【解析】这是冒泡排序,外层循环变量 i 从 10 递减到 2,每一趟要在前 i 个元素之间做相邻比较,因此内层循环从 1 到 i-1,故 [11] 处填 i - 1。交换分两步完成:先把后一个元素上移到前一个位置,故 [12] 处填 A(k, 2) = A(k + 1, 2)。数组中第一列存放号码、第二列存放成绩,交换成绩之后必须把号码也一起交换,否则数据错位,故 [13] 处填 A(k, 1) = A(k + 1, 1)。
2023年真题|第132题 下列程序的功能是找出 n×m 矩阵中的最大数及其位置。请将程序补充完整。
Private Sub Command1_Click()
N = InputBox("请输入数组第一维上界")
M = InputBox("请输入数组第二维上界")
[14]________ A(N, M)
For i = 1 To N
For j = 1 To M
[15]________ = InputBox("请输入数组元素 A(" & i & "," & j & ")")
Next j
Next i
End Sub
Private Sub Command2_Click()
Max = [16]________
For i = 1 To N
For j = 1 To M
If Max < A(i, j) Then
Max = [17]________
I1 = [18]________
J1 = [19]________
End If
Next j
Next i
End Sub
【答案】[14] ReDim;[15] A(i, j);[16] A(1, 1);[17] A(i, j);[18] i;[19] j
【解析】矩阵的行数与列数由用户输入,事先并不知道,因此数组要用动态数组,在 Dim 语句中括号留空、此处再用 ReDim 按 N 与 M 重新定义,故 [14] 处填 ReDim。输入数据时要给当前元素赋值,故 [15] 处填 A(i, j)。求最大值时初值应取数组中的实际元素,取左上角的 A(1, 1) 最稳妥,故 [16] 处填 A(1, 1)。发现更大的元素就更新最大值,故 [17] 处填 A(i, j);同时要把它的位置记下来,行号存入 I1、列号存入 J1,故 [18] 处填 i、[19] 处填 j。
2024年真题|第137题 在比赛中常计算修剪平均值,即去掉最高分和最低分计算其余分数的平均值作为最后成绩。单击命令按钮,由键盘接收七个评委的打分,然后计算修剪平均值(保留 1 位小数),输出每位评委的打分、最高分、最低分和最后成绩。程序如下,请补充完善程序。
Private Sub Command1_Click()
Dim fen As Single, i As Integer, total As Single, fmax As Single, fmin As Single
fen = InputBox("请输入第1位评委打分")
Print "评委打分:"; fen;
fmax = fen: fmin = fen: total = fen
For i = 2 To 7
fen = InputBox("请输入第" & i & "位评委打分")
Print fen;
If fmax [23]________ fen Then fmax = fen
If fmin [24]________ fen Then fmin = fen
total = [25]________
Next i
Print
Print "去掉一个最高分"; fmax
Print "去掉一个最低分"; fmin
Print "最后得分"; Int((total - fmax - fmin) / 5 * 10 + 0.5) / 10
End Sub
【答案】[23] <;[24] >;[25] total + fen
【解析】fmax 中保存的是当前为止的最高分,只要新读入的分数比它还大,就应当把它换掉,故 [23] 处填小于号 <。fmin 中保存的是当前为止的最低分,新读入的分数比它还小时才替换,故 [24] 处填大于号 >。每读入一个分数都要累加到总和中,故 [25] 处填 total + fen。循环结束后,从总和中减去最高分与最低分,再除以 5,就得到修剪平均值。
2025年真题|第129题 在窗体上有一按钮 Command1,用户从键盘上输入十个学生的成绩,计算平均分和高于平均分人数并输出到窗体上。程序如下,请补充完善程序代码。
Private Sub Command1_Click()
Dim s(1 To 10) As Integer
Dim p!, n%, i%
p = 0
For i = [7]________ To 10
s(i) = InputBox("请输入第" & i & "个学生的成绩")
p = [8]________
Next i
p = [9]________
For i = 1 To 10
If [10]________ Then n = n + 1
Next i
Print "平均分="; p, "高于平均分人数="; n
End Sub
【答案】[7] 1;[8] p + s(i);[9] p / 10;[10] s(i) > p
【解析】数组 s 的下标从 1 到 10,输入循环也应当从 1 开始,故 [7] 处填 1。每读入一个成绩都要把它累加到变量 p 中,故 [8] 处填 p + s(i)。十个成绩全部累加完后,p 中存放的是总分,求平均分要除以人数 10,故 [9] 处填 p / 10;此时 p 已经由总分变成平均分。第二个循环用来统计高于平均分的人数,判断条件是当前成绩大于平均分,故 [10] 处填 s(i) > p。
2025年真题|第131题 下面程序运行,单击窗体上的按钮 Command1,从键盘上输入完成一个 5×5 的矩阵的数据,找出其中最大的数和所在位置,然后将结果显示在窗体上。请将程序代码补充完善。
Private Sub Command1_Click()
Dim A(1 To 5, 1 To 5) As Integer, Tmax As Integer, II As Integer, JJ As Integer
For i = 1 To [19]________
For j = 1 To [20]________
A(i, j) = InputBox("请输入a(" & i & "," & j & ")的值")
Next [21]________
Next i
Tmax = A(1, 1)
II = 1
JJ = 1
For i = 1 To 5
For j = 1 To 5
If A(i, j) > Tmax Then
Tmax = [22]________
II = [23]________
JJ = [24]________
End If
Next j
Next i
Print "矩阵中最大数是"; Tmax; "位于第"; II; "行"; JJ; "列"
End Sub
【答案】[19] 5;[20] 5;[21] j;[22] A(i, j);[23] i;[24] j
【解析】题目要求处理 5×5 的矩阵,两重循环的终值都是 5,故 [19]、[20] 两处都填 5。内层循环的结束语句要跟内层循环变量 j 配套,故 [21] 处填 j。输入完成后程序令 Tmax、II、JJ 都取第一个元素及其位置作为初值,随后逐行逐列扫描:发现更大的元素就把最大值换成它,故 [23] 处填 A(i, j);同时把行号记入 II、列号记入 JJ,故 [24] 处填 i、[25] 处填 j。(说明:该题原卷第 [22] 空位于输入循环结束之后、最大值赋初值之前,按程序逻辑此处不需要任何语句,应为原卷排版所致,故本讲义按 6 空收录。)
2026年真题|第130题 窗体上有一个命令按钮 Command1、一个文本框 Text1、两个标签,程序运行后用户在文本框中输入 5 至 25 之间的整数 n,单击 Command1,则随机生成 n 个 0 到 20 之间的数显示在标签上,并找到最大值显示在另一个标签上。程序代码如下,请完善程序代码。
Private Sub Form_Load()
Dim a() As Integer
End Sub
Private Sub Command1_Click()
n = [17]________(Text1.Text)
If (n > 25 [18]________ n < 5) Then
MsgBox "n 值在5至25之间", vbOKOnly, "信息提示"
Exit Sub
End If
[19]________ a(n) As Integer
Randomize
For i = [20]________ To n - 1
a(i) = Int(Rnd * [21]________)
Next i
s = ""
m = a(0)
For i = [22]________ To n - 1
If (m < a(i)) Then m = [23]________
s = s + Str(a(i))
Next i
Label2.Caption = "生成的随机数有:" + s
Label3.Caption = "其中的最大数是:" + Str(m)
End Sub
【答案】[17] Val;[18] Or;[19] ReDim;[20] 0;[21] 21;[22] 1;[23] a(i)
【解析】文本框中的内容一律按字符串处理,要把其中的数字取出参加运算,应使用 Val 函数转换,故 [17] 处填 Val。判断 n 是否超出范围,只要"大于 25"或者"小于 5"两者之一成立就应当报错,故 [18] 处填逻辑运算符 Or。数组 a 在窗体的 Load 事件中已声明为空括号的动态数组,此处要按 n 指定它的大小,故 [19] 处填 ReDim。ReDim a(n) 生成的数组下标从 0 到 n 共 n+1 个,而题干要求生成 n 个数,循环从 0 取到 n-1 正好 n 次,故 [20] 处填 0。要产生 0 到 20 之间的随机整数,应把 Rnd 乘以 21 再取整,故 [21] 处填 21。求最大值时第一个元素已作为初值取走,比较从下标 1 开始,故 [22] 处填 1;发现更大就更新最大值,故 [23] 处填 a(i)。
【练习题】
一、填空题
1. 用数组求最大值时,最大值变量的初值应当取数组中的________,而不能取 0。
【答案】第一个元素
【解析】求最大值时先假定某个元素最大,再逐个与其余元素比较、发现更大就替换。这个初值必须取自数组本身,通常取第一个元素。若把初值取成 0,当数组元素全部为负数时 0 反而最大,最终输出就会是一个并不在数组中的结果。
2. 求最大值时,除了用变量保存最大值之外,还要用另外的变量保存它的________;求最小值时,比较的方向应当反过来,当前元素________暂定最小值时才替换。
【答案】下标(位置);小于
【解析】只有当题目要求指出最大数"在哪里"时,才需要用另外的变量把它的位置记下来。做法是在更新最大值变量的同一时刻,把当前的循环变量(也就是下标)赋给位置变量,这样两者始终对应同一个元素。求最小值与求最大值的思路完全一样,只是把判断方向反过来,当前元素小于暂定最小值时才替换。
3. 用数组求平均值,应当先________,再除以元素的个数。
【答案】求和
【解析】求平均值分两步:先把各个元素累加起来得到总和,再把总和除以元素的个数。累加变量必须在进入循环之前清零,否则会把上一次运行或其他计算残留的数值带进来,使平均值偏大。
4. 冒泡排序中,外层循环控制________,内层循环控制每一趟中________的次数。
【答案】趟数;比较
【解析】冒泡排序每一趟都把相邻的两个元素依次比较一遍,使当前范围内的最大数沉到末尾,因此需要若干趟才能排好,外层循环正是用来控制趟数的。每一趟中要比较多少次,则由内层循环控制,而它的终值要随外层循环变量递减。
5. 选择排序法与顺序比较法的区别是:发现更小的元素时先用一个变量记下它的________,等内层循环结束后再互换。
【答案】下标
【解析】顺序比较法一旦发现更小的元素就立即互换,交换次数较多;选择排序法则先在遍历过程中用变量记下最小元素的下标、暂不互换,等内层循环结束之后再交换一次。这样每趟最多只交换一次,效率明显更高。
6. 处理二维数组要用两层循环,外层循环处理________,内层循环处理________;输出时应当在每一行打印完后________。
【答案】行;列;换行
【解析】二维数组的元素要按逐行扫描的方式访问,因此外层循环变量作行号、内层循环变量作列号。输出时如果在每一行打印完毕之后不换行,所有的数据就会挤在同一行上,看不出矩阵的行列结构。
二、单项选择题
1. 用数组求最大值时,最大值变量的初值应当取( )
A. 0
B. 数组的第一个元素
C. 数组的最后一个元素
D. 任意值都可以
【答案】B
【解析】求最大值前先假定某个元素最大,再逐个与其余元素比较。这个初值必须取自数组本身,通常取第一个元素,首尾哪一个都可以,但绝不能取 0。若取 0 而数组元素全部为负数,0 反而成了最大值,结果必然出错。
2. 若数组元素全部为负数,把求最大值变量的初值取 0 会导致( )
A. 结果正确
B. 程序出错
C. 结果为最小值
D. 结果为 0
【答案】D
【解析】初值 0 比数组中任何一个负数都大,比较过程中没有任何元素能够替换它,循环结束后最大值变量里仍然是 0。程序不会报错,只是输出的结果是一个并不属于该数组的数字。
3. 求最大值的循环中,一旦发现当前元素比暂定的最大值大,就应当( )
A. 更新最大值变量并记下当前下标
B. 交换两个元素
C. 结束循环
D. 重新开始循环
【答案】A
【解析】发现更大的元素时,只需把这个元素换到最大值变量中,同时把当前的下标记到位置变量里,两者要同步更新。求最大值不需要交换元素,也不应结束或重新开始循环,因为后面还可能有更大的数。
4. 冒泡排序每一趟比较的是( )
A. 第 i 个元素与其后的每一个元素
B. 首尾两个元素
C. 相邻的两个元素
D. 随机两个元素
【答案】C
【解析】冒泡排序在每一趟中把相邻的两个元素依次比较,不符合次序就互换,使较大的数逐步向后移动、最终沉到末尾。第 i 个元素与其后每一个元素逐一比较,是顺序比较法与选择排序法的做法,不是冒泡排序。
5. 冒泡排序中,外层循环的作用是( )
A. 控制比较的次数
B. 交换两个元素
C. 输出结果
D. 控制排序的趟数
【答案】D
【解析】每一趟只能把当前范围内的最大数沉到末尾,要把全部元素排好需要若干趟,因此外层循环用来控制趟数;每一趟内部要比较多少次,则由内层循环控制。交换元素是循环体中条件成立时才执行的语句。
6. 选择排序法与顺序比较法相比,优点是( )
A. 交换次数更少
B. 比较次数更少
C. 不需要循环
D. 不需要数组
【答案】A
【解析】两种方法的比较过程完全相同,比较的次数也一样多。区别在于选择排序法发现更小的元素时先记下下标、暂不互换,等内层循环结束之后再交换一次,因而每趟最多只交换一次,交换次数明显少于顺序比较法。
7. 统计高于平均分的人数时,一般需要( )
A. 只遍历一次数组
B. 先求平均分,再遍历一次数组
C. 不需要数组
D. 用三层循环
【答案】B
【解析】统计的条件是"成绩高于平均分",而平均分本身要先由全部数据算出来,因此必须先完整遍历一次求平均分,再遍历第二次逐个比较、统计人数。只遍历一次无法完成,也不需要使用三层循环。
8. 统计满足条件的元素个数,计数变量在循环之前应当( )
A. 设为 1
B. 设为最大值
C. 清零
D. 不必处理
【答案】C
【解析】计数变量用来累计符合条件的元素个数,必须在进入循环之前清零,否则会把上一次运行或其他计算残留的数值带进来,结果偏大。若把它误设为 1,最终结果又会比实际个数多 1。
9. 用二维数组时,外层循环一般处理( )
A. 行
B. 列
C. 单个元素
D. 整个数组
【答案】A
【解析】二维数组按逐行扫描的方式访问,外层循环变量作行号、内层循环变量作列号,两个变量合起来才能确定一个元素的下标。若把行与列颠倒过来,虽然仍能访问到全部元素,但输出的次序就不再是自然的行优先顺序。
10. 二维数组输出时,若不在一行打印完后换行,则( )
A. 程序出错
B. 只输出第一行
C. 只输出最后一列
D. 所有数据挤在一行上
【答案】D
【解析】Print 方法每执行一次会自动换行,若在内层循环中只逐个打印元素、不在内层循环结束后单独执行一次空 Print,那么全部数据就会连续输出在同一行上,看不出矩阵的行列结构。程序并不会出错,只是显示效果不对。
11. 按分数段分类统计人数时,常用元素值整除 10 的结果作为( )
A. 循环变量
B. 计数变量
C. 数组元素的下标
D. 条件的界限
【答案】C
【解析】分数段的划分以十位为界,把分数整除 10 之后,0 到 10 之间的分数都会落到同一个下标上,用这个结果作为存放人数的数组下标,就可以用一条语句完成归类;分数恰好为 100 时要单独处理。
12. 在冒泡排序中若数组还有另一列数据(如号码),互换时必须( )
A. 只交换成绩列
B. 两列一起交换
C. 只交换号码列
D. 先交换号码不交换成绩
【答案】B
【解析】数组的每一行原本是一组对应关系:第一列是号码、第二列是成绩。交换时若只动成绩列,号码就与原来的成绩脱钩,输出出来的名次与号码会张冠李戴;若只动号码列,成绩又不动,排序等于没做。因此必须两列一起交换。
三、程序填空题
1. 下列程序求出数组中的最大值及其下标。请补充完整下列程序代码。
Option Base 1
Private Sub Command1_Click()
Dim a(1 To 8) As Integer, i As Integer
Dim mx As Integer, pos As Integer
For i = 1 To 8
a(i) = Val(InputBox("请输入数据"))
Next i
mx = [1]________
pos = 1
For i = 2 To 8
If a(i) > mx Then
mx = a(i)
pos = [2]________
End If
Next i
Print "最大值="; mx; "下标="; [3]________
End Sub
【答案】[1] a(1);[2] i;[3] pos
【解析】求最大值时初值应取数组中的实际元素,这里取第一个元素 a(1),故 [1] 处填 a(1);位置变量随即也置为 1,表示当前最大值的下标是 1。当发现更大的元素时,除了更新最大值变量,还要把当前下标赋给位置变量,故 [2] 处填 i。最后要输出最大值的下标,输出的是位置变量,故 [3] 处填 pos。
2. 下列程序用冒泡排序法把数组元素按从小到大的顺序排列。请补充完整下列程序代码。
Option Base 1
Private Sub Form_Click()
Dim a(1 To 6) As Integer, i As Integer, j As Integer, t As Integer
For i = 1 To 6
a(i) = Int(Rnd * 90) + 10
Next i
For i = 5 To 1 Step -1
For j = 1 To [1]________
If a(j) > a(j + 1) Then
t = a(j)
a(j) = a(j + 1)
a(j + 1) = [2]________
End If
Next j
Next i
For i = 1 To 6
Print a(i);
Next i
End Sub
【答案】[1] i;[2] t
【解析】这是冒泡排序,外层循环变量 i 从 5 递减到 1,表示每一趟的范围,内层循环要在前 i+1 个元素之间做相邻比较,共比较 i 次,故 [1] 处填 i。交换两个元素需要借助一个临时变量 t:先把 a(j) 存入 t,再把 a(j+1) 赋给 a(j),最后把暂存在 t 中的原 a(j) 交还给 a(j+1),故 [2] 处填 t。
原创精品资源学科网独家享有版权,侵权必究
学科网(北京)股份有限公司
$