Golang - Part04 数组和切片
数组
Go语言中的数组是一种固定长度且类型相同的数据结构。数组中存储的元素可以通过索引来访问,索引从0开始,最大值为数组长度-1。数组的长度在创建时指定,并且无法更改。
初始化数组
- 声明一个具有3个整数的数组:
- 声明并初始化一个具有5个整数的数组:
1
| arr := [5]int{1, 2, 3, 4, 5}
|
- 声明并初始化一个具有5个整数的数组,其中第2个和第4个元素被省略:
1
| arr := [5]int{1, , 3, , 5}
|
- 使用”…”语法声明并初始化一个具有5个整数的数组:
1
| arr := [...]int{1, 2, 3, 4, 5}
|
相关用法
遍历数组
直接for循环遍历数组:
1 2 3 4
| arr := [5]int{1, 2, 3, 4, 5} for i := 0; i < len(arr); i++ { fmt.Println(arr[i]) }
|
可以使用range关键字来遍历数组:
1 2 3 4
| arr := [5]int{1, 2, 3, 4, 5} for index, value := range arr { fmt.Println(index, value) }
|
数组也支持多维数组:
1 2 3 4 5 6 7 8
| var arr [3][2]int arr = [3][2]int{ {1, 2}, {3, 4}, {5, 6}, } fmt.Println(arr[0][0]) fmt.Println(arr[1][1])
|
以下是使用数组和切片实现斐波那契数列的例子:
1 2 3 4 5 6 7 8 9
| func FibonacciArray(n int) []int { arr := make([]int, n) arr[0], arr[1] = 1, 1 for i := 2; i < n; i++ { arr[i] = arr[i-1] + arr[i-2] } return arr }
|
切片
切片(slice)是对数组的一个连续片段的引用。切片可以动态增长,并且支持所有原生的数组操作。
初始化切片
- 声明一个空的整数切片:
- 声明并初始化一个整数切片:
1
| slice := []int{1, 2, 3, 4, 5}
|
- 使用make函数创建一个长度为5的整数切片:
- 使用make函数创建一个长度为5,容量为10的整数切片:
1
| slice := make([]int, 5, 10)
|
- 多维切片
1 2
| s9 := [][]int{{1, 2, 3}, {11, 12, 13, 14}} fmt.Printf("s9 的长度:%d,容量:%d\n", len(s9), cap(s9))
|
在Go语言中,切片可以通过索引来访问、修改元素:
1 2 3 4 5
| slice := []int{1, 2, 3, 4, 5} fmt.Println(slice[0])
slice[0] = 10 fmt.Println(slice)
|
相关用法
切片还支持使用append函数动态增加元素:
1 2 3 4 5
| slice := make([]int, 3, 5) slice[0], slice[1], slice[2] = 1, 2, 3
slice = append(slice, 4, 5) fmt.Println(slice)
|
可以使用len和cap函数获取切片的长度和容量:
1 2 3
| slice := make([]int, 3, 5) fmt.Println(len(slice)) fmt.Println(cap(slice))
|
切片还支持使用内置的copy函数复制切片:
1 2 3 4
| slice1 := []int{1, 2, 3} slice2 := make([]int, len(slice1)) copy(slice2, slice1) fmt.Println(slice2)
|
在Go语言中,可以使用切片来实现栈和队列等数据结构。
以下是使用切片实现栈的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| type Stack []int
func (s *Stack) Push(value int) { *s = append(*s, value) }
func (s *Stack) Pop() int { if s.IsEmpty() { return -1 } index := len(*s) - 1 result := (*s)[index] *s = (*s)[:index] return result }
func (s *Stack) IsEmpty() bool { return len(*s) == 0 }
stack := make(Stack, 0) stack.Push(1) stack.Push(2) stack.Push(3) fmt.Println(stack.Pop()) fmt.Println(stack.Pop()) fmt.Println(stack.Pop()) fmt.Println(stack.IsEmpty())
|
去重排序查找
可以使用sort包对切片进行排序。sort包支持对int、float64、string等类型的切片进行排序。
1 2 3 4 5 6 7 8 9 10
| import ( "fmt" "sort" )
func main() { slice := []int{5, 1, 3, 2, 4} sort.Ints(slice) fmt.Println(slice) }
|
sort包还支持对自定义类型的切片进行排序,只需要实现sort.Interface接口中的三个方法:Len()、Less()和Swap()。
切片排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import ( "fmt" "sort" )
type Person struct { Name string Age int }
type PersonSlice []Person
func (p PersonSlice) Len() int { return len(p) }
func (p PersonSlice) Less(i, j int) bool { return p[i].Age < p[j].Age }
func (p PersonSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func main() { persons := PersonSlice{ {"Tom", 20}, {"John", 18}, {"Mary", 25}, } sort.Sort(persons) fmt.Println(persons) }
|
切片查找
在Go语言中,可以使用sort.Search函数对有序切片进行二分查找。
以下是对有序整数切片进行二分查找的例子:
1 2 3 4 5 6 7 8 9 10 11 12
| import ( "fmt" "sort" )
func main() { slice := []int{1, 2, 3, 4, 5} index := sort.Search(len(slice), func(i int) bool { return slice[i] >= 3 }) fmt.Println(index) }
|
如果切片中不存在要查找的元素,则返回元素应该插入的位置。
以下是对有序字符串切片进行二分查找的例子:
1 2 3 4 5 6 7 8 9 10 11 12
| import ( "fmt" "sort" )
func main() { slice := []string{"apple", "banana", "orange", "peach"} index := sort.Search(len(slice), func(i int) bool { return slice[i] >= "orange" }) fmt.Println(index) }
|
切片去重
在Go语言中,可以使用map实现对切片进行去重。
以下是对整数切片进行去重的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import ( "fmt" )
func RemoveDuplicates(slice []int) []int { tempMap := make(map[int]bool) tempSlice := []int{} for _, value := range slice { if !tempMap[value] { tempMap[value] = true tempSlice = append(tempSlice, value) } } return tempSlice }
func main() { slice := []int{1, 2, 3, 1, 4, 2, 5} slice = RemoveDuplicates(slice) fmt.Println(slice) }
|