内容正文:
项目9 数组
2
[项目导入]
求100个学生的平均成绩及超过平均成绩的人数。如果用一般变量来表示成绩,需要用100个变量,如:mark1、 mark2、…、 mark100。若用数组,可以只用一个来表示mark(1 to 100)。
在处理大批数据时,使用数组可以缩短程序代码、提高程序的可读性和执行效率。
根据数组对内存占有的情况可将其分为:
静态数组:先分配存储空间,运行过程中不再改变。
动态数组:使用完成后即可释放数组空间,也可重新利用。
3
任务1 数组的基本概念
任务2 一维静态数组的程序设计
任务3 二维数组的应用
任务4 动态数组
任务5 控件数组
4
本章目标
掌握数组的概念、分类。
熟练掌握(一维、二维)(静态、动态)数组的声明 以及数组的输入、输出。
熟练掌握(一维、二维) )(静态、动态)数组的程序设计方法。
掌握Array函数、Preserve参数的使用。
了解控件数组的建立及使用。
重点:数组声明、数组的赋值及输出、动态数组的重定义(redim)、array函数、preserve参数使用
难点:动态数组的声明及重定义、数组典型算法实例(最值问题、选择排序、冒泡排序、数组元素兑换)
5
任务1 数组的基本概念
排列有序、个数有限、有统一名称、不同下标、具有相同的数据类型(一般情况)、的一组数。
备注:数据类型,一般情况数组具有相同的类型,若是变体型数组,各个元素能够包含不同类型的数据
1 数组和数组元素
例如:A(n)
说明:A为数组的名称,n为下标变量,A(1)表示
A数组的第一个元素,A(n)表示A数组的第n个元素,
数组中每个元素具有唯一的索引号。
6
任务1 数组的基本概念
数组的维数由下标的个数决定。即一维数组1个下标,二维数组2个下标。
最多60维
下标:表示顺序号,具有唯一性,不能超过数组声明时的上、下界范围。下标可以是整型的常数、变量、表达式,还可以是一个数组元素。
下标的取值范围:下界 to 上界,缺省下界时,系统默认取0。
2 数组的维数
7
任务1 数组的基本概念
数组在使用时要严格遵循先定义后使用的原则。
在程序的通用对象声明部分可用语句:
(1)Option Base 1,意味着声明所有数组第1个元素下标为1
(2)Option Base 0,意味着声明所有数组第1个元素下标为0(默认值)
(3)Option Base 语句必须放在数组定义之前。
静态数组声明的语法格式1:
Option Base 0或1
Dim 数组名(下标1,[下标2…])[as 类型]
作用:声明了数组的名称、维数、大小、类型
说明:下标必须为常数,默认下标最小为0
3 静态数组的声明
例如:Dim y(5) as integer
说明:y为 integer类型数组,
y数组的最小下标从0开始,
最大下标为5,即数组中有
6个数: y(0) 、 y(1) 、 y(2)、
y(3) 、 y(4)、 y(5) 。
再例如 option base 1
Dim y(5) as integer
说明:y为 integer类型数组,
y数组的最小下标从1开始,
最大下标为5,即数组中有
5个数: y(1) 、 y(2)、 y(3) 、
y(4)、 y(5) :
8
任务1 数组的基本概念
静态数组声明的语法格式2:
Option Base 0或1
Dim 数组名(下界1 to 上界1,[下界2 to 上界2…])[as 类型]
说明:
(1)每一维的大小:上界-下界+1
(2)数组大小: 每一维大小的乘积
3 静态数组的声明
例如:
Dim x(1 to 5) as integer ‘x是一个一维整型数组,有5个元素
Dim a(-2 to 5,3) as integer ‘a是一个二维整型数组,有[5-(-2)+1]*[3-0+1]=32个元素
9
任务2 一维静态数组的程序设计
掌握静态数组的声明以及数组的输入、输出。
掌握一维静态数组的程序设计方法。
任务目标:
10
例: 最值平均值问题
例9.1 用数组计算某组5名同学的平均成绩及优秀率
分析:
(1)输入5个学生的成绩并累计求和。
(2)统计成绩在85分以上的学生的人数。
(3)求出平均成绩及优秀率。
创建用户界面
11
例: 最值平均值问题
设置属性
表9-1属性设置
编写事件代码
Option Base 1 ‘通用部分声明
Dim a(5) As Single
Private Sub Form_Load() ‘数组元素赋值
a(1) = 84:a(2) = 63:a(3) = 79:a(4) = 95:a(5) = 86
End Sub
对 象 属 性 属 性 值 说 明
Form1 Caption 成绩分析 窗体的标题
Label1 Caption 平均分: 标签的内容
Label2 Caption 优秀率: 标签的容
Command1 Caption 统计(&c) 命令按钮的标题
12
例: 最值平均值问题
编写事件代码
Private Sub Command1_Click() '统计按钮
Dim i As Integer, n As Integer, sum As Single, aver As Single, exse As Single
For i = 1 To 5 '累计求和
sum = sum + a(i)
If a(i) >= 85 Then ’统计优秀的人数
n = n + 1
End If
Next i
aver = sum / 5 '计算平均分
exse = (n / 5) * 100 '计算优秀率
Label1.Caption = Label1.Caption + Format(aver)
Label2.Caption = Label2.Caption + Format(exse) + "%"
End Sub
运行结果如图
13
例: 最值平均值问题
例9.3 随机产生10个两位整数,放入数组A中,输出其中的最大的数及下标。
分析:假设法。
(1)设用max来存放选出的最大数
(2)先假设第一个元素最大,然后依次与后面的元素进行比较,若后面的元素大于假设值,则重新赋值……
编写事件代码(窗体单击事件)
Option Base 1
Private Sub Form_Click()
Dim a(10) As Integer
Dim i As Integer, max As Integer, p As Integer
For i = 1 To 10 ‘产生并输出10个 随机整数
a(i) = Int(Rnd * 90 + 10)
Print a(i);
Next i
14
例: 最值平均值问题
编写事件代码(窗体单击事件)
max = a(1) '假设法
p = 1
For i = 2 To 10 ‘判断比较
If a(i) > max Then
max = a(i) ’重新赋值
p = i
End If
Next i
Print "最大值max="; max, "下标p="; p
End Sub
运行结果
15
例: 最值平均值问题
拓展 随机产生10个两位整数,找出其中的最大值、最小值和平均值
分析:假设法。
(1)先任意产生一个数,并假设其是最大的也是最小的。
(2)在循环结构中,判断新产生的数与假设的最值之间的关系,若出现比最大值大比最小值小的情况,则重新赋值。
16
例: 最值平均值问题
编写事件代码
Private Sub Command1_Click() ‘计算输出 按钮
Dim a(1 To 10) As Integer
Dim i As Integer, sum As Integer, ave As Single _ max As Integer, min As Integer
For i = 1 To 10 '产生并输出10个 随机整数
a(i) = Int(Rnd * 90 + 10)
Print a(i); " ";
Next i
max = a(1) '假设法
min = a(1)
sum = a(1) '累计求和
For i = 2 To 10 '判断比较
sum = sum + a(i)
If a(i) > max Then max = a(i)‘重新赋值
If a(i) < min Then min = a(i)
Next i
ave = sum / 10 '计算平均值
Text1.Text = max ’输出结果
Text2.Text = min
Text3.Text = ave
End Sub
运行结果如图所示
17
例: 统计各段的个数问题
例9.2 统计0-9,10-19,20-29,…,80-89,90-99分数段及100分的学生人数
分析:
(1)用数组an来存放各分数段的人数。An(0)存放0-9分的人数,An(1)存放10-19分的人数,……An(9)存放90-99分的人数, An(10)存放100分的人数
(2)把输入的成绩x\10转换成下标t,代替多个并列的if语句。
创建用户界面
18
例: 统计各段的个数问题
编写事件代码
Option Base 1 ’通用部分声明
Private Sub Form_Click()
Dim an(10) As Integer, i As Integer, x As Integer
For i = 1 To 10 ‘产生10个分数并判断分数段
x = Val(InputBox("请输入第" & Str(i) & "个学生的成绩", "输入成绩"))
If x < 60 Then
an(5) = an(5) + 1
Else
t = x \ 10
an(t) = an(t) + 1
End If
Next i
Print “0分-59分:”; an(5)’输出结果
Print "60分-69分:"; an(6)
Print "70分-79分:"; an(7)
Print "80分-89分:"; an(8)
Print "90分-99分:"; an(9)
Print "100分:"; an(10)
End Sub
19
例: 统计各段的个数问题
拓展:统计输入的一串字母中各个字母出现的次数(不区分大小写)
分析:
若按照大写字母统计:
(1)用数组cs统计各个字母出现的次数,即cs(1)存放字母A出现的次数, cs(2)存放字母B出现的次数,… cs(26)存放字母Z出现的次数。
(2)依次取出字符串中的每个字母c,判断c是否在A-Z这个范围内 ,通过ASCII值(65-90)确定数组的下标。
创建用户界面
20
例: 统计各段的个数问题
编写事件代码
Dim c As String, cs(1 To 26) As Integer, i as integer
For i = 1 To Len(Text1.Text)
c = UCase(Mid(Text1.Text, i, 1))
If c >= "A" And c <= "Z" Then
j = Asc(c) - 64
cs(j) = cs(j) + 1
End If
Next i
For j = 1 To 26
If cs(j) > 0 Then Text2.Text = Text2.Text & Chr(j + 64) & "=" & cs(j)
Next j
21
例: 倒序输出问题
题型一:将下列10个字符a、b、c、d、e、f、g、h、i、j存放到数组中,并以倒序打印出来。
分析:
(1)把10个字符存放在数组a(10)中。
(2)首先依次读取,然后利用for循环,步长设置为-1,实现倒序输出
创建用户界面
22
例: 倒序输出问题
编写事件代码
Private Sub Command1_Click()
Dim x As Integer, a(1 To 10) As String
a(1) = "a": a(2) = "b": a(3) = "c": a(4) = "d": a(5) = "e"
a(6) = "f": a(7) = "g": a(8) = "h": a(9) = "i": a(10) = "j"
For x = 1 To 10
Label1.Caption = Label1.Caption & a(x) '按原字符顺序输出
Next x
For x = 10 To 1 Step -1
Label2.Caption = Label2.Caption & a(x) '按倒序输出
Next x
End Sub
23
例: 倒序输出问题
题型二:数组元素对换。
设某数组有10个元素,元素的值由键盘输入,要求将前5个元素与后5个元素对换,即第1个元素与第10个元素互换,第2个元素与第9个元素互换,…第5个元素与第6个元素互换,输出数组原来各元素的值和对换后各元素的值。
分析:
(1)定义一个具有10个元素的数组a(1 to 10),首先利用for循环对其赋值,然后按此顺序输出,即为互换前各元素的值。
(2)进行互换操作时,方法是将a (i)与a(10-i+1)互换,最后输出互换后各元素的值。
24
例: 倒序输出问题
创建用户界面及设置对象属性
25
例: 倒序输出问题
编写事件代码
Dim a(1 To 10) As Integer
Private Sub Command1_Click()
Dim i As Integer, t As Integer, p As String
For i = 1 To 10
a(i) = Val(InputBox("请输入a(" & Format(i, "#") & "):"))
p = p & “,” & a(i) ’输入的原始数组元素
Next i
Label1.Caption = p
End Sub
26
例: 倒序输出问题
编写事件代码
Private Sub Command2_Click()
Dim p As String
For i = 1 To 5 ‘对换代码
t = a(i)
a(i) = a(10 - i + 1)
a(10 - i + 1) = t
Next I
For i = 1 To 10
p = p & “,” & a(i) ’对换后的数组元素
Next i
Label2.Caption = p
End Sub
27
数组元素对换的算法
以N个元素为例:
1)判断交换的次数N\2
2)互换的两个元素a(i)与a(N-i+1)
28
例: 数据排序问题
选择排序
例9.4 由计算机随机产生6个两位正整数,将这6个数按从小到大的顺序排序。
算法分析:
顺序比较法 (低效排序)
(1)对有n个数的序列,从中选出最小的数(递增)与第1个数交换位置。即拿数组中的第1个数与后面的n-1个数依次比较,选出最小的数放在第1个数的位置
(2)除第一个数以外,其余n-1个数再按(1)的方法选出次小的数,与第2个数交换位置
即拿数组中的第2个数与后面的n-2个数依次比较,选出次小的数放在第2个数的位置
(3)重复(2)n-1遍,最后构成递增序列。
总结
N个数需要进行n-1趟排序
第一趟进行n-1次比较,第二趟进行n-2次比较,以此类推
29
例: 数据排序问题
顺序排序法核心代码(递增)
For i = 1 To N – 1 ‘N-1趟
For j = i + 1 To N ‘每一趟比较次数
If a(i) > a(j) Then t = a(i): a(i) = a(j): a(j) = t
Next j
Next i
30
例: 数据排序问题
编写事件代码
Private Sub Form_Click()
Dim a(1 To 6) As Integer, temp As Integer, i%, j%, k%
Print "排序前:";
For i = 1 To 6
a(i) = Int(Rnd * 90 + 10) '产生数据
Print a(i);
Next i
Print
Print "排序后:";
For i = 1 To 5 '排序
For j = i + 1 To 6
If a(i) > a(j) Then temp = a(i): a(i) = a(j): a(j) = temp
Next j
Next i
For i = 1 To 6
Print a(i); '排序后输出
Next i
End Sub
运行结果
31
例: 数据排序问题
选择排序
例9.4 由计算机随机产生6个两位正整数,将这6个数按从小到大的顺序排序。
算法分析:
选择法排序(经典排序)
比较过程和顺序比较法一致,只是发现小的元素用k记下下标,不交换,内循环结束时再交换。
32
例: 数据排序问题
选择法排序核心代码(递增)
For i = 1 To N – 1 ‘N-1趟
k=i ’用k记录小的元素的下标
For j = i + 1 To N ‘每一趟比较次数
If a(k) > a(j) Then K=j
Next j
t = a(i): a(i) = a(k): a(k) = t
Next i
33
例: 数据排序问题
冒泡排序
例9.4 由计算机随机产生6个两位正整数,将这6个数按从小到大的顺序排序。
算法分析:
(1)第一趟,将每相邻的两个数进行比较,小的调到前头,经5次两两相邻比较后,最大的数已“沉淀”,放在最后一个位置,小数上升“浮起”
(2)第二趟,对余下的5个数(最大的数已“沉淀”)按上述方法比较,经4次两两相邻比较后得次大的数。
(3)依次类推,6个数共进行5趟比较,在第j趟中要进行6-j次两两比较。
总结
N个数需要进行n-1趟排序
第一趟进行n-1次比较,第二趟进行n-2次比较,以此类推
34
例: 数据排序问题
冒泡排序核心代码(递增)
For i = 1 To N – 1 ‘N-1趟
For j = 1To N-i ‘每一趟比较次数
If a(j) > a(j+1) Then t = a(j): a(j) = a(j+1): a(j+1) = t
Next j
Next i
35
例: 数据排序问题
编写事件代码
Private Sub Form_Click()
Dim a(1 To 6) As Integer, temp As Integer, i%, j%, k%
Print "排序前:";
For i = 1 To 6
a(i) = Int(Rnd * 90 + 10) '产生数据
Print a(i);
Next i
Print
Print "排序后:";
For i = 1 To 5 '排序
For j = 1 To 6-i
If a(j) > a(j+1) Then temp = a(j): a(j) = a(j+1): a(j+1) = temp
Next j
Next i
For i = 1 To 6
Print a(i); '排序后输出
Next i
End Sub
运行结果
$$