0%

【Go】内建容器

那时候
车马慢
一生只够爱一人
—— 《醉千年》

数组

定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 直接定义一个空的数组
var arr1 [5]int
fmt.Println("arr1 = " , arr1)
// 数组的基本赋值方式之一
arr2 := [3]int{2,4,5}
fmt.Println("arr2 = " , arr2)
// 切片的方式
arr3 := [...]int{1,2,3,4,5,6,7,8,9}
fmt.Println("arr3" , arr3)
// 4 行 5 列
var grid [4][5]int
fmt.Println("arr4 = " , grid)
// 数组的遍历
for i , v := range arr3{
fmt.Printf(" i = %d , v = %d \n", i, v)
}

Note:

1
2
3
4
5
6
7
8
9
10
11
func printArray(arr [5]int){
for i , v := range arr{
fmt.Printf(" i = %d , v = %d \n", i, v)
}
}

func printArray(arr []int){
for i , v := range arr{
fmt.Printf(" i = %d , v = %d \n", i, v)
}
}

在Go语言中,[]int 和 [5]int 是有区别的,[]int 其实就是一个切片,[5]int 其实是一个实实在在的数组。

  • [10]int 和 [20]int 是不同类型
  • 调用 func f(arr [10]int) 会拷贝数组,即原数组不会发生改变
  • go 语言中一般不直接使用数组

切片(Slice)

在Go语言中,一般不使用数组,使用比较多的就是切片。

1
2
3
4
arr3 := [...]int{1,2,3,4,5,6,7,8,9}
fmt.Println("arr3" , arr3)
s := arr3[2:6]
fmt.Println("s = " , s)

这里的 s 其实就是一个切片,表示的是从 [2,6) 区间内的值。

1
2
3
s := arr3[0:6]
s := arr3[2:0]
s := arr3[:]

当然也可以这么去写。

  • Slice 是切片,是arr 的一个视图,不是值类型的。这个可以写一个函数,参数是 []int ,在里面修改 []int 的值,就知道了。
  • Slice是arr的视图,看的是整个数组,并不是你所切片的那部分
  • Slice 可以再继续的 Slice, 新的Slice 看的也是 原数组 arr
  • 当为一个Slice做 append 的时候,arr 数组是不会有任何变化的,
    1
    2
    3
    4
    5
    6
    arr3 := [...]int{1,2,3,4,5,6,7,8,9}
    fmt.Println("arr3" , arr3)
    s := arr3[2:6]
    slice2 := s[3:5]
    fmt.Println("s = " , s)
    fmt.Println("slice2 = " , slice2)
    结果如下:
    1
    2
    s =  [3 4 5 6]
    slice2 = [6 7]
    现在可以看到,我们的 slice6 连同7 一并取出来了,但是在我们的 s 切片里面是没有 7 的。大家看个图:
    slice-1

图中的 slice 所取的切片,并不是到了标号6的位置后,就停止了,其实里面还是有值的,前面说了,切片其实是对数组的一个 view . 这也就是为什么我们能看到 7 的原因。我们可以看下这个 slice 的机构组成。
slice-2

1
2
3
4
5
// 如果不知道切片的数据内容,要创建一个切片,我们用 make
// 创建一个 []int 的切片,长度为16 的切片
s1 := make([]int , 16)
// 创建一个 []int 的切片,长度为16 的,容量为 32 的切片
s1 := make([]int , 1632)

Map

map的定义和我们Java里面的 map 其实是一样的,也是 kv 键值对。看个示例代码:

1
2
3
4
5
6
7
8
m := map[string]string{
"key": "value",
"language": "go",
}

for k, v := range m {
fmt.Printf("k = %s , v = %s \n", k, v)
}
  • 这里的 map 里面的存储的话,并不是按照顺序存储的。
  • 如果取值 map 里面不存的值的时候,取到的是一个空值
    1
    2
    3
    4
    5
    if s, ok := m["sun"]; ok {
    fmt.Printf("vlaue = %s , is exists %s \n", s, ok)
    }else {
    fmt.Println("no exists")
    }
  • 创建操作: make(map[string]string)
  • 删除操作: delete(map , key)
  • map 使用 hash 表,必须可以相等
  • 除了 slice , map , function的内建类型都可以作为 key
  • Struct 不包含上述结构,也可以作为 key

寻找最长不含有重复字符的子串

1
2
3
abcabcbb -> abc ,
bbbbb -> b
pwwkwe -> wke

思路:

查找 字母 x :

  • lastOccurred[x] 不存在 或者 < start -> 无需任何操作
  • lastOccurred[x] >= start , start = lastOccurred[x] + 1
  • 更新 lastOccurred[x] , 更新 maxLength
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func lengthOfNoRepeatingSubStr(str string) int {
lastOccurred := make(map[byte]int)
start := 0
maxLength := 0
// 这里先转成 byte
for index , ch := range []byte(str){

if lastIndex , ok := lastOccurred[ch]; ok && lastIndex >=start{
start = lastIndex + 1
}
if index -start +1 > maxLength {
maxLength = index - start + 1
}
lastOccurred[ch] = index
}
return maxLength
}
这是打赏的地方...

本文标题:【Go】内建容器

文章作者:Mr.Sun

发布时间:2020年05月21日 - 09:13:23

最后更新:2020年06月10日 - 14:29:42

原始链接:http://www.blog.sun-iot.xyz/posts/6d5668f8

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

---------Thanks for your attention---------