Golang學習筆記(2)內建容器

第二章 內建容器(數組,切片和容器)


數組

var arr1 [5]int
arr2 := [3]int{1,3,5}
arr3 := [...]int{2,3,4,5,6}	// 編譯器識別數組長度
var grid[4][5] int
  • 數組長度寫在數組類型的前面
  • 遍歷數組
// 基本遍歷方法
func printArray(arr [5]int) {
	for i := 0; i < len(arr); i++ {
		fmt.Println(i, arr[i])		
	}
}
// 使用range遍歷
func printArray(arr [5]int) {
	for i, v := range arr {	// i : index v : value
		fmt.Println(i, v)
	}
}
  • 數組是值類型(作爲函數參數是值傳遞)
  • [10]int 和 [20]int 是不同的類型
  • go語言中一般不直接使用數組

Slice 切片

1. Slice本身沒有數據,是對底層arry的一個view, 修改Slice的值會修改對應的arry的值

arr := [...]int {0, 1, 2, 3, 4, 5, 6, 7}
slice1 = arr[2:6]	// arr[2] ~ arr[5] --  [2 3 4 5 6]
slice2 = arr[2:]	// arr[2] ~ arr[7] --  [2 3 4 5 6 7]
slice3 = arr[:6]	// arr[0] ~ arr[5] --  [0 1 2 3 4 5]
sliceAll = arr[:]	// arr全部

func updateSlice(s []int) {	// 傳入Slice, 修改index = 0的數據
	s[0] = 100
}

2. ReSlice

arr := [...]int {0, 1, 2, 3, 4, 5, 6, 7}
s := arr[2:6]	// [2,3,4,5]
s = s[:3] 		// [2,3,4]
s = s[1:]		// [3,4]
s = s[:]		// [3,4]

3. Slice的實現

ptr 指向Arry的某一個index, 作爲Slice的index = 0的位置
len 爲Slice的長度, s[index] 的index必須 >= 0 && < len, 否則會 out of range
cap 爲從ptr開始到Arry最後一個元素的長度

在這裏插入圖片描述

4. Slice的擴展

arr := [...]int {0, 1, 2, 3, 4, 5, 6, 7}
s1 = arr[2:6]		// [2,3,4,5]
s2 = s1[3:5]		// [5,6] -- s1[5]對於s1來說不存在, 但是由於Slice的可擴展性, 可以正確指向到 arr[5]
					// 但是單獨取 s1[5] 會 out of range
fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))	 // s1=[2 3 4 5] len(s1)=4 cap(s1) = 6
fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n", s2, len(s2), cap(s2))	 // s1=[5 6] len(s2)=2 cap(s1) = 3
  1. Slice可以向後擴展,不可以向前擴展
  2. s[i] 不可以超越 len(s), 向後擴展不可以超越底層數組的cap(s)
    在這裏插入圖片描述

5. 向Slice添加元素

s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Println("s3, s4, s5 =", s3, s4, s5) // s3, s4, s5 = [5 6 10] [5 6 10 11] [5 6 10 11 12]
// s4 and s5 no longer view arr.
fmt.Println("arr =", arr)				// arr = [0 1 2 3 4 5 6 10]
  • 添加元素時如果超越cap,系統會重新分配更大的底層數組
  • 由於值傳遞的關係,必須接收append的返回值

6. 創建Slice

var s []int					// [], len=0, cap=0
s1 := []int{2, 4, 6, 8}		// [2 4 6 8], len=4, cap=4
s2 := make([]int, 16)		// [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap=16
s3 := make([]int, 10, 32)	// [0 0 0 0 0 0 0 0 0 0], len=10, cap=32

7. 拷貝Slice

copy(s2, s1)		// s2 = [2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap=16

8. 刪除Slice中的元素

// 刪除s2[3]
s2 = append(s2[:3], s2[4:]...)		// s2 = [2 4 6 0 0 0 0 0 0 0 0 0 0 0 0], len=15, cap=16
// 移除首個元素
front := s2[0]			// front  = 2
s2 = s2[1:]				// s2 = [4 6 0 0 0 0 0 0 0 0 0 0 0 0], len=14, cap=15
// 移除末位元素
tail := s2[len(s2)-1]	// tail = 0
s2 = s2[:len(s2)-1]		// s2 = [4 6 0 0 0 0 0 0 0 0 0 0 0], len=13, cap=15

在移除元素的時候,len(slice)始終會減少, 但是cap(slice)只有在移除首個元素的時候纔會減少
因爲在移除首個元素的時候,Slice的ptr發生了改變,向後移動了一個元素, cap的長度自然也要減少

Map 容器

1. Map結構

 map[K]V
 map[K1(map[K2]V)

2. 創建Map

m := map[string]string{
	"name":    "ccmouse",
	"course":  "golang",
	"site":    "imooc",
	"quality": "notbad",
}

m2 := make( map[string]int ) // m2 == "map[]"

3. 遍歷map, 不保證遍歷順序

for k, v := range m {
	fmt.Println(k, v)
}

4. 獲取數據m[key],如果輸入的key不存在,返回的是ZeroValue( “map[]” )

courseName := m["course"]

5. 用value, ok:=m[key]來判斷是否存在key

if causeName, ok := m["cause"]; ok {
	fmt.Println(causeName)
} else {
	fmt.Println("key 'cause' does not exist")
}

6. 刪除數據

delete(m, "name")

7.使用len獲取元素個數

len(m)

8. map的key

map使用哈希表,必須可以比較相等
除了slice,map,function的內建類型都可以作爲key
Struct類型不包含上述字段,也可以作爲key

rune

  • rune相當於go的char
  • 使用 utf8.RuneCountInString 獲取字符數量
  • 使用 len 獲得字節長度
  • 使用 []byte 獲得字節

練習

尋找最長不含有重複字符串的子串

  • lastOccurred[x]不存在,或者 < start ->無需操作
  • lastOccurred[x] >= start -> 更新start
  • 更新lastOccurred[x],更新maxLength
func lengthOfNonRepeatingSubStr(s string) int {
	lastOccurred := make(map[rune]int)
	start := 0
	maxLength := 0

	for i, ch := range []rune(s) {
		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
			start = lastI + 1
		}
		if i-start+1 > maxLength {
			maxLength = i - start + 1
		}
		lastOccurred[ch] = i
	}

	return maxLength
}

func main() {
	fmt.Println(
		lengthOfNonRepeatingSubStr("abcabcbb"))
	fmt.Println(
		lengthOfNonRepeatingSubStr("bbbbb"))		
	fmt.Println(
		lengthOfNonRepeatingSubStr("pwwkew"))
	fmt.Println(
		lengthOfNonRepeatingSubStr(""))
	fmt.Println(
		lengthOfNonRepeatingSubStr("b"))
	fmt.Println(
		lengthOfNonRepeatingSubStr("abcdef"))
	fmt.Println(
		lengthOfNonRepeatingSubStr("這裏是慕課網"))
	fmt.Println(
		lengthOfNonRepeatingSubStr("一二三二一"))
	fmt.Println(
		lengthOfNonRepeatingSubStr(
			"黑化肥揮發發灰會花飛灰化肥揮發發黑會飛花"))
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章