Presentation is loading. Please wait.

Presentation is loading. Please wait.

第五章 数组.

Similar presentations


Presentation on theme: "第五章 数组."— Presentation transcript:

1 第五章 数组

2 教学要求 掌握数组的定义和使用 掌握动态数组的定义和使用 掌握控件数组的建立和使用 掌握常用算法 2

3 教学内容 5.1 数组的概念 5.2 数组的基本操作 5.3 动态数组 5.4 控件数组 5.5 程序示例 3

4 5.1 数组的概念 数组命名与数组元素 数组定义 数组的结构 数组函数及数组语句 4

5 基本概念 本章我们要介绍的是一种下标变量——数组,是通过一个数组名和下标的组合来表示多个值。用一个相同的名字引用一组变量的数据。
前面所说的变量都是指简单变量,即一个变量名对应一个存储单元,只能存储一个值,各个变量之间无关联。 本章我们要介绍的是一种下标变量——数组,是通过一个数组名和下标的组合来表示多个值。用一个相同的名字引用一组变量的数据。 数组,是VB支持的一种复合结构的数据类型。 数组,是用于保存一组具有相同数据类型的有序的变量的集合。 5

6 5.1.1 数组命名与数组元素 命名规则与简单变量相同。(参阅P45) 数组名不是代表某一变量,而是一组变量。 数组元素:
由数组名和该元素在数组中的编号(索引、下标)唯一确定,下标是连续的整数。 数组元素的一般形式: 数组名(下标1[,下标2,…]) 数组的维数: 一维数组——只需一个下标即可唯一确定一个数组元素 多维数组——有两个或两个以上下标的数组,每个下标对应一个“维”。 6

7 5.1.2 数组定义 数组必须先定义后使用。 定义数组时,确定其名称、数据类型、维数、每一维的上、下界。
数组定义 数组必须先定义后使用。 定义数组时,确定其名称、数据类型、维数、每一维的上、下界。 数组定义时,系统分配连续的内存空间,用于依次保存所有数组元素。 固定大小数组与动态数组。 7

8 1、数组说明语句 [格式]: Public|Private|Static|Dim 数组名([<下界1> To]<上界1> [,[<下界2> To]<上界2>,…]) As 类型 [说明]: 声明关键字决定作用域,见下页 <下界> TO <上界> 决定了每一维的大小,下界指下标的最小值,上界指下标的最大值,其中 [<下界> TO]可省略,此时,默认下界是0。 我们习惯于下标是从1开始,可在模块的“通用”声明段中使用如下语句 Option Base 1 则在缺省下界的情况下,默认下界是1。 8

9 注意:全局数组、 全局符号常量和全局定长字符串只能在标准模块中定义
关键字 使用位置 作用域 Public 在标准模块的声明段中 全局 Private和Dim 在模块的声明段中 模块 Dim 在过程中 局部 Static 局部、静态 注意:全局数组、 全局符号常量和全局定长字符串只能在标准模块中定义 9

10 举例 注意:在声明语句中的A(6)是数组说明符, 而在程序其他语句出现的A(6)是一个数组元素。 - Dim a(6) as integer
Private Name(1999 to 2002) as string *8 Dim b(2,1 to 2) as integer 数组元素分别为:a(0)、a(1)、a(2)、a(3)、a(4)、a(5)、a(6),共7个 数组元素分别为:name(1999) name(2000) name(2001) name(2002) , 用于保存长度为8的字符串数据。 数组元素分别为:b(0,1),b(0,2),b(1,1),b(1,2),b(2,1),b(2,2) 注意:在声明语句中的A(6)是数组说明符, 而在程序其他语句出现的A(6)是一个数组元素。 10

11 × 2 数组的上、下界 上、下界表示下标的最大、最小值; 下界≤上界; 在固定大小数组定义时,上、下界是常量或常量表达式,不得是变量;
2 数组的上、下界 上、下界表示下标的最大、最小值; 下界≤上界; 在固定大小数组定义时,上、下界是常量或常量表达式,不得是变量; 上、下界应是整数,若不是,则自动四舍五入。 举例: Dim m as integer Const n=5 as integer Dim a(n) as integer Dim b(1 to 6.6) as integer Dim c(1 to 2*3) as integer Dim d(0 to m) as integer × 11

12 3 数组的类型 4 数组的大小 可为任一简单数据类型 指数组中包含元素的个数。 一维数组元素个数:上界-下界+1 二维数组元素个数:
3 数组的类型 可为任一简单数据类型 4 数组的大小 指数组中包含元素的个数。 一维数组元素个数:上界-下界+1 二维数组元素个数: (上界1-下界1+1)*(上界2-下界2+1) 12

13 5.1.3 数组的结构 数组的所有元素是按一定顺序存储在连续的存储单元的。 1.一维数组的结构 例:Dim stra(3)
数组的结构 数组的所有元素是按一定顺序存储在连续的存储单元的。 1.一维数组的结构 例:Dim stra(3) 逻辑结构:(stra(0),stra(1),stra(2) stra(3)) 存储结构:按照下标从小到大依次存储 Str(0) Str(1) Str(2) Str(3) 13

14 2 二维数组的结构 例:Option base 1 Dim y(3,4) as integer 逻辑结构:
2 二维数组的结构 例:Option base 1 Dim y(3,4) as integer 逻辑结构: y(1,1),y(1,2),y(1,3),y(1,4) y(2,1),y(2,2),y(2,3),y(2,4) y(3,1),y(3,2),y(3,3),y(3,4) 存储结构: “按列存放” 14

15 3 三维数组的结构 行、列和页组成的三维表。 逻辑结构:见书P88 存储结构:“逐页逐列” 15

16 5.1.4 数组函数及数组语句 1、返回上、下界函数: 举例: 上界:UBound(数组名[,d]) 下界:LBound(数组名[,d])
数组函数及数组语句 1、返回上、下界函数: 上界:UBound(数组名[,d]) 下界:LBound(数组名[,d]) 说明:d代表维数。省略时表示返回第一维的值。 Dim A(5) As Integer, B(2, 3 to 5) As Integer a1=LBound(A) a1=UBound(A) b1=LBound(B,1) b2=LBound(B,2) b3=UBound(b,1) b4=UBound(b,2) Print a1;a2;b1;b2;b3; b4 举例: 对数组元素依次进行处理,需通过循环结构,循环的次数即数组元素的个数,而知道数组的上下界就知道元素的个数 结果: 16

17 (3) Erase 初始化数组语句 格式: Erase a1[,a2,...] 功能:对普通数组初始化(按数组类型给元素赋初值),
对动态数组进行存储空间释放。例:p.89 Option Base 1 Private Sub Form_Click() Dim a(3) As Integer a(1) = 1: a(2) = 2: a(3) = 3 Print a(1), a(2), a(3) Erase a End Sub 17

18 (4) For Each-Next 数组循环结构
格式: For Each Element In <数组名> 语句块 [Exit For] Next [Element] 功能:依次(存储次序)处理每一个数组元数,直到数组结束。 说明: Element是Variant变量,它逐个地代表数组中的每一个变量。 18

19 例: 请注意:只能一行或一列输出,不能以矩阵形式输出。参见p90 Private Sub Form_Click()
Dim E(2, 3) As Integer, V As Variant Dim i As Integer, j As Integer For i = 1 To 2 For j = 1 To 3 E(i, j) = i * 10 + j Next j Next i For Each V In E Print V; Next V End Sub 强调了解功能即可 处理顺序为该数组的存储顺序——按列! 19

20 5.2 数组的基本操作 数组元素的赋值 数组元素的输出 数组元素的引用 20

21 5.2.1 数组元素的赋值 一维数组用一层循环结构 1 用赋值语句给单个数组元素赋值。 Dim score(3) as integer
1 用赋值语句给单个数组元素赋值。 Dim score(3) as integer score(1)=90 : score(2)=80 : score(3)=68 2 在循环结构中,用赋值语句逐一给数组元素赋值。 Dim a(1 to 6) as integer For i=1 to 6 a(i)=int(99*rnd)+1 Next i 3 在循环结构中,利用Inputbox函数给数组元素赋值。 一维数组用一层循环结构 演示程序,说明三种赋值的特点:1只适用于少量元素的数组 2适用于数组元素为随机数或有规律 3适用于指定数组元素的值的情况 Dim a(1 to 6) as integer For i=1 to 6 a(i)=inputbox(“请输入a(” & I & ”)”,”数组赋值”) Next i 21

22 4、Array赋值函数 格式:变体变量名=Array([n1,n2,...])
功能:将一个变体型变量创建成为一个一维数组,并包含指定的元素。元素的引用方式与一般数组一样。 注意:Array赋值函数只能给变体型变量赋值。不能给其他类型的变量及任何类型的数组赋值。 Option Base 1 Private Sub Form_Click() Dim a As Variant, b As Integer a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) Print a(1), a(5), a(10) a = "Array" Print a b = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) End Sub 22

23 5.2.2 数组元素的输出 5.2.3 数组元素的引用 用Print方法显示在窗体或图片框上 赋值给文本框的Text属性,在文本框中显示
数组元素的输出 用Print方法显示在窗体或图片框上 赋值给文本框的Text属性,在文本框中显示 调试时,调用Debug的Print方法在“立即”窗口中显示 数组元素的引用 注意:在引用数组元素时,元素的下标一定要在定义的上下界范围之内,否则“数组越界”出错。 23

24 例5-1 产生12个两位数,从中找出最大值 、最小值
Option Base 1 Private Sub Form_click() Dim compare(12) As Integer, i As Integer Dim max As Integer, min As Integer Randomize For i = 1 To 12 compare(i) = Int(90 * Rnd) + 10 Print compare(i); Next i Print Print "最大数是;"; max Print "最小数是;"; min End Sub 例5-1 产生12个两位数,从中找出最大值 、最小值 max = compare(1): min = compare(1) For i = 2 To 12 If compare(i) > max Then max = compare(i) ElseIf compare(i) < min Then min = compare(i) End If Next i (1)演示各种输出方法; (2) 演示下标溢出错误 (3)介绍循环控制标量I在两个循环中的作用 24

25 例: 有一个一维数组a(20) ,要求按照每行6个元素的格式输出。数组元素为100-200之间的随机数。
Option Base 1 Private Sub Form_Click() Dim a(20) As Integer Dim i As Integer, j As Integer For i = 1 To 20 a(i) = Int(101 * Rnd) + 100 Next i End Sub For i = 1 To 20 Print a(i) ; j = j + 1 Next i 演示通常的三种输出格式:紧凑、标准和分行;再介绍按题目要求进行的分行显示。 If j Mod 6=0 Then Print 25

26 例:二维数组的赋值与输出 二维数组引用必须用二重循环实现 Option Explicit Option Base 1
Private Sub Form_Click() Dim i As Integer, j As Integer Dim a(3, 4) As Integer Randomize For i = 1 To 3 For j = 1 To 4 a(i, j) = Int(Rnd * ) Next j Next i Print a(i, j) ; Print End Sub 程序分析: 程序执行时,计数变量i和j的变化为: i=1时,j从1变化到4,结束内层循环,i变成2 i=2时,j从1变化到4,结束内层循环,i变成3 i=3时,j从1变化到4,结束内层循环,i变成4 结束外层循环。循环变量(i , j)的变化过程为 (1,1)(1,2)(1,3)(1,4) (2,1)(2,2)(2,3)(2,4) (3,1)(3,2)(3,3)(3,4) 正好和二维数组引用的下标一致。 For i = 1 To 3 For j = 1 To 4 s=s & a(i, j) Next j s=s & Chr(13) & Chr(10) Next I Text1.Text=s For i = 1 To 3 For j = 1 To 4 Picture1.Print a(i, j) ; Next j Picture1.Print Next i 二维数组引用必须用二重循环实现 26

27 Print "第"; i; "行元素之和为:"; sum
例:下列程序完成在窗体上输出二维数组每行元素之和。回答问题: 1、程序有没有错? 2、错在哪里?3、输出语句应出现在什么地方? Option Base 1 Private Sub Form_Click() Dim a(4, 5) As Integer Dim i As Integer, j As Integer Dim sum As Integer For i = 1 To 4 For j = 1 To 5 a(i, j) = Int(101 * Rnd) + 100 Print a(i, j); Next j Print Next i sum = sum + a(i, j) Next I Print "第"; i; "行元素之和为:"; sum End Sub 程序执行结果界面 介绍调试的作用 Sum=0 Print "第"; i; "行元素之和为:"; sum 27

28 有关二维数组的常见问题: 转置 求对角线元素之和 求周边元素之和 求上、下三角形元素之和 求鞍点、最大、最小元素 二维数组相乘 28

29 例:产生一个3行4列的矩阵,数据为[20,50]之间的随机数,然后将矩阵转置输出。
Option Base 1 Private Sub Form_Click() Dim i As Integer, j As Integer, a(3, 4) As Integer Randomize For i = 1 To 3 For j = 1 To 4 a(i, j) = Int(Rnd * ) Print a(i,j); Next j Print Next I End Sub 介绍按行和按列访问数组元素的不同表示 For i = 1 To 4 For j = 1 To 3 Print a(j ,i); Next j Print Next i For j= 1 To 4 For i= 1 To 3 Print a( i , j); Next j Print Next i 思考题: 求n阶方阵的转置矩阵,并输出? 29

30 练 习 1、分别求一个3*3二维数组的主、付对角线元素之和。 2、求二维数组周边元素之和。 30

31 5.3 动态数组 静态数组与动态数组 静态数组: 定义:在程序运行过程中,可重新定义大小的数组。 说明语句:
5.3 动态数组 定义:在程序运行过程中,可重新定义大小的数组。 说明语句: ① Dim 数组名()as 类型 —在变量说明部分 ② ReDim [Preserve] <数组名>(维界定义)—在可执行语句中 Private Sub Form_Click() Dim Pin( ) As Integer '说明整型的动态数组Pin Dim x as Integer X=Val(Text1.text) ReDim Pin(x) '重新说明数组Pin ... End Sub 静态数组与动态数组 静态数组: 在说明数组时,如果指明了数组的维数和每一维的下标范围,在使用过程中,它的维数和下标范围将不得改变,这样的数组就称为“静态数组”。 注意:- Redim 是可执行语句,只能出现在过程中 - 重新定义动态数组时,不能改变数据类型 - 重定义时,维界定义中可以有变量 31

32 说 明 - 如果Redim重定义的数组不存在,则相当于一个说明语句
说 明 - 如果Redim重定义的数组不存在,则相当于一个说明语句 - 当缺省Preserve参数时,定义后,原来存储在数组中的数据全部丢失,此时可重新定义数组的维数和各维的上下界。 - 当有Preserve参数时,可保留原数组中的数据,但不能改变数组的维数,且只能改变最后一维的维上界。 - 用Dim语句声明过的数组,只是一个空数组,系统并没有给它分配内存空间,此时,不能对数组元素进行存取操作,否则出错。必须用ReDim语句重新定义其大小,系统才给它分配内存,用户才能对此数组元素进行操作。 32

33 举例: Option base 1 Dim dynarry() as integer
Dim x as integer,y as integer Dynarry(1)=1 Redim dynarry(9) x=2:y=4 Redim dynarry(x,y) Dynarry(1,1)=1 Erase dynarry 非法语句,出错 给一维数组元素赋值 给二维数组元素赋值 非法语句,出错 33

34 举 例 如果省去 Preserve,会怎样? Option Explicit Option Base 1
举 例 Option Explicit Option Base 1 Private Sub Form_Click() Dim i As Integer, a() As Integer ReDim a(4) For i = 1 To 4 a(i) = i Print a(i); Next i Print ReDim Preserve a(6) a(5) = 5 a(6) = 6 For i = 1 To 6 End Sub 如果省去 Preserve,会怎样? 34

35 例:找出1000以内的所有完数并以指定的格式在列表框中输出。所谓完数,是指它的所有的质因子之和等于它本身的数,如6=1+2+3。
解题思路: 第一步:找出确定一个数是完数 的方法; 第二步:从1到1000依次判断。 算法实现: 两层循环: 内层循环用于找出某数 m 的所有因子并相加求和,并在循环结束后依据因子和是否与该数相等来判断该数是否是完数; 外层循环则用于穷举所有1000以内的整数。 35

36 注意s、k赋初值的位置 s = 0: k = 0 Private Sub Command1_Click()
Dim i As Integer, j As Integer, s As Integer, k As Integer Dim str1 As String, a() As Integer For i = 1 To 1000 For j = 1 To i – 1 If i Mod j = 0 Then ’是因子,保存进数组并累加求和 s = s + j End If Next j If s = i Then ‘是完数,按指定格式输出 Next i End Sub s = 0: k = 0 注意s、k赋初值的位置 k = k + 1 ReDim Preserve a(k) a(k) = j str1 = CStr(i) & "=" For j = 1 To k str1 = str1 & CStr(a(j)) & "+" Next j List1.AddItem left(str1,len(str1)-1)

37 5.4 控件数组 基本概念 建立控件数组 使用控件数组 Load语句 Unload语句 37

38 5.4.1 基本概念 —— 由一组具有相同名称的同类型控件组成。 —— 控件数组中的每个控件都由其下标属性-Index 标识。
基本概念 —— 由一组具有相同名称的同类型控件组成。 —— 控件数组中的每个控件都由其下标属性-Index 标识。 即:控件数组名(下标) 如,Option1(0)、 Option1(1)、 Option1(2) —— 控件数组中的每一个控件元素可有自己独立的属性设置,但共享同一个事件过程,即无论是控件数组中的哪一个控件响应用户的事件,都触发同一事件过程,但相对于简单控件,事件过程增加了Index参数,由其指明具体响应的控件。 例如:Private Sub Option1_Click(Index As Integer) End Sub ——注意:控件数组的第一个下标为0 ——优点:使用控件数组编写代码简单、易于维护 38

39 5.4.2 建立控件数组 1. 创建同名控件 在窗体中放置一组控件(同类型),确定某个控件为第一个元素(可将其Index属性设为0)。
建立控件数组 1. 创建同名控件 在窗体中放置一组控件(同类型),确定某个控件为第一个元素(可将其Index属性设为0)。 按顺序将其它控件的Name(名称)属性改成第一个控件名称(同名)。 系统提示“已有一个控件为***,创建一个控件数组吗?”,若第一个控件的Index属性已设为0,则不出现提示。 39

40 2. 复制现存控件 系统给每个数组控件标明唯一的索引号, 即为该对象的Index属性(下标)。 在窗体中放置一个控件,设置好相应的属性
选定该控件,单击“复制”按钮 单击“粘贴”按钮 系统提示”已有一个控件为***,创建一个控件数组吗?” 单击“是”按钮 观察控件Index 属性, 系统给每个数组控件标明唯一的索引号, 即为该对象的Index属性(下标)。 40

41 Private Sub Command1_Click(Index as integer) … … Select case index
例如:在窗体上有一个包含四个命令按纽的控件数组。这4个命令按纽的名称相同,均为Command1 ,系统通过下标---Index属性,区别4个不同的控件:Command1(0),Command1(1),Command1(2),Command1(3)。 这个由4个按纽组成的命令按纽控件数组,具有相同的事件过程,由参数Index决定,到底是哪个按纽被触发。在事件过程中,应根据Index参数,分别进行不同的操作。 Private Sub Command1_Click(Index as integer) … … Select case index Case 0 Case 1 …… End select End Sub 41

42 3.运行时,用语句添加、删除控件数组中的控件
LOAD 语句 [格式] load object(index) [功能] 在程序运行时,向控件数组中添加控件。 UNLOAD语句 [格式] unload object(index) [功能] 在程序运行时,删除控件数组中的控件。 明白了吗?还是上机验证一下吧! 注 意 - index可以跳序; - UNLOAD语句只能删除由LOAD 语句添加的控件; - 由LOAD 语句添加的控件,其Visible 属性为false,所以要在程序中设置True,才能在窗体上可见; - 由LOAD 语句添加的控件,其大小、位置与原控件一样,隐藏在其背后,所以要重新设置它的Top等属性; Private Sub Command1_Click(Index As Integer) Load Command1(5) Command1(5).Visible = True Command1(5).Left = 10 End Sub Private Sub Command2_Click() Unload Command1(5) 42

43 演示裁判 43

44 Private Sub Form_Load() Dim i As Intege For i = 0 To 5
Text1(i).Text = “” Label1(i).Caption = "裁判" & i + 1 Next i End Sub Private Sub Command1_Click() Dim i As Integer, score As Single For i = 0 To 5 score = score + Val(Text1(i)) Next i score = score / 6 Text2.Text = Format(score, "##.##") End Sub Private Sub Text1_KeyPress(Index As Integer, KeyAscii As Integer) If KeyAscii = 13 Then If Index = 5 Then Command1.SetFocus Else Text1(Index + 1).SetFocus End If End Sub 44

45 5.5 程序示例 选择法排序 冒泡法排序 顺序查找 二分查找 45

46 例5-2:选择法排序。(设从大到小排序) [分析]:先将N个数存入数组A(N),
第一轮比较,将A(1)与A(2)比较,若A(1)<A(2),则交换A(1)和A(2)的值;再将A(1)与A(3) 、A(4) … A(N)依次按以上规则比较和交换,第一轮比较完毕,N个数中最大数存放到A(1)中 第二轮比较,将A(2)与A(3)、A(4)…A(N)依次比较,结束后,N个数中第二大数存放到A(2)中; 第三轮比较,将A(3)与A(4)、A(5)…A(N)依次比较,完毕后,N个数中第三大数存放到A(3)中; 第N-1轮比较,A(N-1)与A(N)进行比较;完毕后,A(N-1)中存放第二小的数,显然A(N)中是最小的数。 这样,数组A中的N个元素经过N-1轮扫视,按从大到小的顺序排列。 46

47 [实例说明]:设无序数据为1、2、3、4、5、6,共有6个元素,进行6-1=5轮比较。5次比较情况如下:
第一轮比较: A(1) a(2) a(3) a(4) a(5) a(6) 第二轮比较: 6、2、1、3、4、5 6、3、1、2、4、5 6、4、1、2、3、5 6、5、1、2、3、4 第三轮比较: 6、5、2、1、3、4 6、5、3、1、2、4 6、5、4、1、2、3 第四轮比较: 6、5、4、2、1、3 6、5、4、3、1、2 第五轮比较: 6、5、4、3、2、1 47

48 [选择排序程序] i 既控制外层循环执行的次数,又可作为被比较数的下标 For i=1 to N-1
For j= i+1 to N If A(i) < A(j) Then TEMP=A(i) A(i)=A(j) A(j)=TEMP End If Next j Next i j 既控制内层循环执行的次数,又可作为比较数的下标 48

49 直接排序法 选择排序法的改进,每轮扫视,只交换一次数据——A(I)仅与其后序元素中最大的元素交换。
实现:增设一个point变量,记录本轮最大元素的下标。在每轮扫视开始时,先设初值为I,然后让A(POINT)依次与其后元素比较,当比某元素小时,将该大元素的下标赋给POINT,即让A(POINT)指向本轮大的元素。 当每轮扫视结束后,比较I与POINT 的值,若不同,说明 A(I)中不是本轮的最大元素,则交换A(I)与A(POINT)中的元素,否则不交换。 49

50 [直接排序程序] For i=1 to N-1 point=i For j= i+1 to N
If A(point) < A(j) Then point=j Next j If i < > point then TEMP=A(i):A(i)=A(point):A(point)=TEMP End if Next i 50

51 例:冒泡法排序。(设从大到小排序) [分析]:
第一轮比较:将A(1)和A(2)比较,若A(1)<A(2)则交换这两个数组元素的值,否则不交换;然后再用A(2)和A(3)比较,处理方法相同;以此类推,直到A(N-1)和A(N)比较后,这时A(N)中就存放了N个数中最小的数。 第二轮比较:将A(1)和A(2)、A(2)和A(3),,A(N-2)和A(N-1)依次比较,处理方法和第一轮相同,这一轮比较结束后,A(N-1)中就存放了N个数中第二小的数。 …… 第N-1轮比较:将A(1)和A(2)进行比较,处理同上,则A(2)中存放了第二大的数,A(1)中显然是最大的数。 这样,经过N-1轮扫视,数组A中的N个元素按从大到小的顺序排列。 51

52 [实例说明]:设无序数据为1、2、3、4、5、6,共有6个元素,进行6-1=5轮扫视。5次扫视情况如下:
第一论扫视: 2、1、3、4、5、6 2、3、1、4、5、6 2、3、4、1、5、6 2、3、4、5、1、6 2、3、4、5、6、1 第二轮扫视: 3、2、4、5、6、1 3、4、2、5、6、1 3、4、5、2、6、1 3、4、5、6、2、1 第三轮扫视: 4、3、5、6、2、1 4、5、3、6、2、1 4、5、6、3、2、1 第四轮扫视: 5、4、6、3、2、1 5、6、4、3、2、1 第五轮扫视: 6、5、4、3、2、1 52

53 j 既控制内层循环执行的次数,又可作为比较数的下标
冒泡排序程序 For i=1 to n-1 For j=1 to n-i If a(j) < a(j+1) Then TEMP=A(j) : A(j)=A(j+1):A(j+1)=TEMP End If Next j Next I i 只控制外层循环执行的次数 j 既控制内层循环执行的次数,又可作为比较数的下标 53

54 改进的冒泡排序 Ub=Ubound(a) Switch=True Do While switch switch=false Ub=ub-1
For j=1 to ub If a(j) < a(j+1) Then swtich=true TEMP=A(j) : A(j)=A(j+1):A(j+1)=TEMP End If Next j Next I 54

55 选择法:逐个比较,逆序交换 冒泡法:两两比较,逆序交换
XZ

56 [分析]:所谓顺序查找,就是将要查找内容与一组数据中的每个元素,依次进行比较,最终得到所要查找内容“存在”或“不存在”的结论。
Private Sub Form_Click() Dim search(10) As Integer, i As Integer Dim S As Integer Randomize For i = 1 To 10 search(i) = Int(Rnd * 100) + 100 Print search(i); Next i Print S = InputBox("输入要查找的数") If search(i) = S Then Exit For If i <= 10 Then Print "要找的数是Search("; i; ")" Else Print "没找到!" End If End Sub 例5-4:顺序查找。 [分析]:所谓顺序查找,就是将要查找内容与一组数据中的每个元素,依次进行比较,最终得到所要查找内容“存在”或“不存在”的结论。

57 [例5-5]:二分查找。 [分析]:二分查找是一种快捷有效的查找方法,使用二分查找的前提是数据序列已排好序。
假设有n个数已经按照从小到大的顺序排列,并存放在数组A中,设Top为查找区间的下界——下标,初值为1;Bot为查找区间的上界,初值为n;设需要查找的数为x;二分查找的算法如下: (1)求出查找区间的中间位置Mid=Int((Top+Bot)/2) (2)若A(Mid)=x,则找到,结束比较 (3)若A(Mid)<x,则表明x在A(Mid+1)到A(Bot)区间内,查找区间缩小一半,设置Top=Mid+1 (4)若A(Mid)>x,则表明x在A(Top)到A(Mid-1)区间内,查找区间缩小一半,设置Bot=Mid-1 (5)重复执行以上操作 (6)结束循环的条件有两个:已经找到;找不到--TOP>BOT 57

58 x=8 3 4 1 11 10 5 9 6 7 8 Left Mid Left Left Mid Left Mid Mid x=5 2 3
Right Mid Right Right Left Mid Mid x=5 2 3 1 11 10 4 9 6 7 8 Left Mid Left Right Mid Right Mid Left Left Mid

59 二分查找 Left = LBound(a) Right = UBound(a) x = InputBox("请输入要查找的数据")
Do While Left <= Right Mid = Int((Left + Right) / 2) If a(Mid) = x Then Exit Do ElseIf a(Mid) < x Then Left = Mid + 1 Else Right = Mid - 1 End If Loop If Left <= Right Then Print "要查找的"; x; "是A("; Mid; ")" Print "没找到!"; x 59

60 例5-8 统计字母(不分大小写)在文本中出现的次数
例5-8 统计字母(不分大小写)在文本中出现的次数 P109 算法分析:建立一个有26个元素的数组,分别保存每个字母出现的次数。下标即是该字母是第几个字母. 60

61 转换为大写字符 控制打印每行统计字符的个数
Private Sub Command1_Click() Dim St As String, Idx As Integer, I As Integer, Js As Integer Dim A(0 To 25) As Integer Dim Ch As String * 1, L As Integer St = Text1.Text: L = Len(St) End Sub 转换为大写字符 For I = 1 To L Ch = UCase(Mid(St, I, 1)) If Ch >= "A" And Ch <= "Z" Then Idx = Asc(Ch) - Asc("A") A(Idx) = A(Idx) + 1 End If Next I 求该字符与“A”的间隔位置,以此作为下标 控制打印每行统计字符的个数 For I = 0 To 25 If A(I) <> 0 Then Js = Js + 1 Text2 = Text2 & Chr(I + Asc("A")) & ":" & Str(A(I)) & " " If Js Mod 5 = 0 Then Text2 = Text2 & Chr(13) & Chr(10) End If Next I

62 外层循环:遍历1——5000以内的所有整数,采用FOR循环,计数控制变量i既控制循环执行的次数,又可作为甲数。
例 找出5000以内的亲密对数。所谓亲密对数,是指甲数的所有因子之和等于乙数,而乙数的所有因子之和等于甲数。如:220的因子和: = 的因子和: =220 算法分析:采用二层循环结构. 外层循环:遍历1——5000以内的所有整数,采用FOR循环,计数控制变量i既控制循环执行的次数,又可作为甲数。 内层循环:求出某数的所有因子,并求和,因为每个数的因子数不确定,所以用动态数组保存因子。 外层循环中:先求出i的因子之和sum1,然后再求出sum1的因子之和sum2,判断sum2是否等于 i,若相等,则输出i和sum1及其因子,不等则继续判断i+1。

63 例 5-11 将一个数列中的重复数删除。 算法分析:
例 将一个数列中的重复数删除。 算法分析: 第一轮,将A(1)与A(2) 、A(3) … A(N) 依次比较,若A(i)与A(1)相同,则删除,删除的方法是将位于A(i)元素之后的元素依次前移一位,即将A(i)覆盖; 第二轮,将A(2)与其后元素依次比较,删除所有与A(2)相同的元素; 循环的次数事先不确定,随重复数的多少而不同,所以采用DO-LOOP循环,循环结束条件是被比较的数组元素a(n)是倒数第二个元素。 与比较数进行比较的数a(i)是从a(n+1)开始到最后一个元素。而一旦发现与a(n)重复的a(i),就利用FOR循环将a(i+1)到最后一个元素依次赋给前一个元素,即将a(i)覆盖删除,同时重新定义数组的大小,减1。 63

64 Do While n < ub ‘循环结束条件为被比较数是倒数第二个元素 i = n + 1 ‘比较数的下标,从N+1开始
ub = UBound(a) n = ‘是被比较数的下标 Do While n < ub ‘循环结束条件为被比较数是倒数第二个元素 i = n ‘比较数的下标,从N+1开始 Do While i <= ub If a(n) = a(i) Then For j = i To ub – 1 ‘ 从a(i+1)到最后一个元素依次前移 a(j) = a(j + 1) Next j ub = ub – ‘数组大小减1 ReDim Preserve a(ub) Else i = i ‘若不相同,再与下一个元素比较 End If Loop n = n ‘被比较数下标加1 64

65 例5-12 15名学生按照已有的编号顺序围成一圈,1~3报数,逢3出局,要求记录学生出局的先后顺序(即编号).
例 名学生按照已有的编号顺序围成一圈,1~3报数,逢3出局,要求记录学生出局的先后顺序(即编号). 算法分析: 需解决如下一个几个问题: 1.如何记录15个学生的编号,又如何围成一圈 2.如何实现报数 3.如何实现逢3出局,并记录下编号 4.已出局的如何不参加报数 定义一个有15个元素的数组,元素下标即编号,当下标依次递增时,若大于15,就回到1. 数组元素的初值为1,顺序对数组元素的值实现累加 当累加和为3时,当前累加的元素出局,记录下其下标 将出局数组元素的值置为0,则累加时不起作用,即不参与报数 65

66 If idx > 15 Then idx = 1 ‘围成一圈,循环
For i = 1 To 15 old_no(i) = 1 Next i idx = 0 count = ‘累加和,起报数作用 Do While count < 3 idx = idx + 1 If idx > 15 Then idx = ‘围成一圈,循环 count = old_no(idx) + count ‘累加求和报数 Loop old_no(idx) = ‘当前元素出局 new_no(i) = idx ‘记录其编号 Text1.Text = Text1.Text & Right(" " & CStr(i), 3) Text2.Text = Text2.Text & Right(" " & CStr(new_no(i)), 3) 66


Download ppt "第五章 数组."

Similar presentations


Ads by Google