数组应用实例
1)创建一个byte类型的26个元素的数组,分别 放置 ‘A’-‘z’。使用 for 循环访问所有元素并打印出来。
提示:字符数据运算 ‘A’+1 -> ‘B’
思路
- 声明一个数组 var letterArr [26]byte
- 使用for循环来进行赋值
- 使用for进行打印
2)求出一个数组的最大值,并得到对应的下标
3)请求出一个数组的和和平均值,for - range
注意平均值问题
4)随机生成5个数,反转打印
注意
- 交换次数 len / 2
- 倒数第一个和第一个元素交换,倒数第二个和第二个交换…
- len(intArr)内建函数调用次数过多,资源浪费
- length := len(intArr)
为什么需要切片?
案例
我们需要用一个数组用于保存学生成绩,但是学生的个数不确定,请问怎么办?
解决方案:使用切片
切片的基本介绍
1)切片的英文 slice
2)切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递机制
3)切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度都是一样
4)切片的长度是可以变化的,因此切片是一个可以动态变化的数组
5)切片定义的基本语法
var 变量名 []类型
比如:var a []int
快速入门
结果
切片内存布局
切片使用的三种方法
- 方式1
- 第一种方式:定义一个切片,然后切片去引用一个已经创建好的数组
- 方式2
- 第二种方式:通过make来创建切片
- 基本语法:var 切片名 []type = make([], len, [cap])
- 参数说明:
- type就是数据类型
- len:大小
- cap:指定切片容量
- 方式3
- 第3种方式:定义一个切片,直接就指定具体数组,原理类似于make
内存分配
切片面试题
1)方式1是直接引用数组,数组事先存在,程序员可见
2)方式2是通过make来创建切片,make也会创建一个数组,是由切片在底层进行维护,程序员是看不见的
切片的遍历
切片的遍历和数组一样有两种方式
1)for循环遍历
2)for-range切片遍历
切片注意事项和细节说明
1)切片初始化时 var slice = arr [startIndex : endIndex]
说明:从arr数组下标为startIndex,取到下标为endIdex(不含 arr[endIndex])
2)切片初始化,不能越界。范围在[0 - len(arr)] 之间, 但是可以动态增长。
- var slice = arr[0 : end] 可以简写:var slice = arr[ : end]
- var slice = arr[start : len(arr)] 可以简写:var slice = arr[start : ]
- var slice = arr[0 : len(arr)] 可以简写:var slice = arr[ : ]
3)cap是一个内置函数,用于统计切片的容量,即最大可以存放多少个元素
4)切片定义完后,还不能使用,因为本身是一个空的,需要让其引用到一个数组,或者make一个空间供切片来使用【声明】
5)定义不能使用,声明后才能使用
6)切片还可以切片
切片内置函数append
func append
内建函数append将元素追加到切片的末尾。若它有足够的容量,其目标就会重新切片以容纳新的元素。否则,就会分配一个新的基本数组。append返回更新后的切片,因此必须存储追加后的结果。
切片操作的底层原理分析
1)切片append操作的本质就是对数组的扩容
2)go底层会创建一个新的数组newArr(安装扩容后大小)
3)将slice原来包含的元素拷贝到新的数组newArr
4)slice重新引用到newArr
5)注意newArr是在底层来维护的,程序员不可见
切片append底层原理分析
最终模型
- 没有引用的数组会被垃圾回收机制回收
切片的copy操作
1)都是切片类型才行
2)数据空间独立,相互不影响
结果
长度不够copy仍有效
结果
string 与切片
1)string的底层是一个byte数组,因此string也可以进行切片处理
2)string是不可变的,str[0]='Z’是行不通的
3)字符串修改,将字符串变成切片,修改后返回字符
相当于substring
结果
string内存图
string的复杂改变
结果
思考题:如果不是@符号,而是是中文该何如???
解决方案:使用,因为rune按处理
代码
结果
切片课堂练习
说明:编写一个函数fbn(n int),要求完成
1)可以接收一个 n int
2)能够将斐波那契数列放入切片中
3)提示,斐波那契数列的数列形式:
arr[0] = 1; arr [1] = 1; arr[2] = 2; arr[3] = 3; arr[4] = 5; arr[5] = 8 …
思路
1)声明一个函数
2)定义声明一个切片
3)for循环存放斐波那契数
代码
结果
排序基本介绍
排序是将一组数据,依照指定的顺序进行排序的过程
排序的分类:
1)內部排序(一次性)
指将需要处理的所有数据都加载到内部存储中进行排序(数据量比较小)
包括(、和)
2)外部排序(一部分一部分加载)
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序
包括(、)。
-
内部排序
-
交换排序
-
1、冒泡排序 (Bubble Sorting)
-
2、快速排序(Quick Sorting)
-
-
冒泡排序法
案例
24,69, 64,100,21 无序数组,进行从小到大的冒泡排序
由内而外的书写
代码
结果
顺序查找
案例
1)有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王
猜数游戏:从键盘任意输入一个名称,判断数列中是否含有此名称【顺序查找】
二分查找
2)对一个有序数组进行二分查找 {1, 8, 10, 89, 100, 123},输入一个数看看该数组是否存在此数,并且求出下标,如果没有 提示“没有这个数”【会使用到递归】
思路分析
分析
1)两个指针,在最两端
2)值比较 (startIndex + endIndex) / 2
3)两端指针变动
代码
结果
快速入门案例
1)利用二维数组打印出
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 0 3 0
0 0 0 0 0 0
代码
二维数组在内存中的布局
二维数组应用案例
定义二维数组,用于保存三个班,每个班5名同学的成绩,
并求出每个班级的平均分,以及所有班级的平均分!
思路
1)二维数组 3个元素,每个元素下含5个元素
2)控制台输入学生成绩
3)求出班平均成绩
4)所有班的平均成绩
代码
结果
map的介绍
map 是key-value 数据结构,又称为字段或者关联数组。类似其它编程语言的集合
map的声明
- 基本语法
- key可以是什么类型?
- bool,数字,string,指针,channel,还可以只包含前面几个类型的 接口,结构体,数组
- 通常为int、string
注意: slice、map、function不可以做key,因为无法用 == 来判断
- value可以是什么类型?
- 与key基本一致
- 通常为:数字(整数、浮点数),string,map,struct
注意:声明是不分配内存的,初始化需要make,分配内存后才能进行赋值和使用
代码
结果
分析
1)map 在使用前一定要 make
2)map 的 key 不能重复,如果重复了,则以最后这个 key - value 为准
3)map 的 value 可以相同
4)map 的 key - value 是无序的
5)make 内置函数不定义size,默认size = 1
map 的3种使用方式
代码
结果
map案例练习
我们要存放3个学生信息,每个学生有name和sex信息
思路
1)map[string]map[string]string
代码
结果
map的增加和修改
存在就是,不存在 就是
map的删除
如何清空 map ?
1)Golang中只能遍历key 进行逐个删除
2)或者 map = make(…), make一个新的空间,让原来的成为垃圾,被GC回收
map的查找
map增删改查总结
代码
输出
map的遍历
1)map的 key 不一定是数字,得用for…range遍历
2)长度用len
结果
map切片(动态增加)
基本介绍:
切片的数据类型如果是map,则我们称为slice of map,map的切片
这样使用map的个数就可以动态变化
注意
1)切片动态增长,用append
代码
结果
map排序
基本介绍:
1)Golang中没有一个专门的方法针对map的key进行排序
2)Golang中的map默认是,遍历也是无序的
3)Golang中map排序,是先将key进行排序,然后根据 key 遍历输出即可
代码
结果
struct做value
1)map是一个引用类型的,可通过函数接收map,进行修改
2)map的容量达到后,再想map增加元素,会自动扩容,并不会发生panic,也就是说map能动态增加(key - value)
3)map的value通常也是结构体struct
代码
结果
map课堂练习
1)使用 map[string]map[string]string 的map类型
2)key表示用户名,是唯一的,不可以重复
3)如果某个用户名存在,就将其密码修改“8888”,如果不存在就增加这个用户信息,包括(昵称nickName 和 password密码)
4)编写一个函数modifyUser(users map[string]map[string]string, name string)完成上述功能
代码
结果
码修改“8888”,如果不存在就增加这个用户信息,包括(昵称nickName 和 password密码)
4)编写一个函数modifyUser(users map[string]map[string]string, name string)完成上述功能
代码
结果