数组
package main
import (
"fmt"
)
func printArr(arr [5]int) {
arr[0] = 100
for i, v := range arr {
fmt.Println(i, v)
}
}
func printArr2(arr *[5]int) {
arr[0] = 100
for i, v := range arr {
fmt.Println(i, v)
}
}
func main() {
var arr1 []int
var arr4 [3]int
arr2 := [5]int{1, 2}
arr3 := [...]int{1, 2, 3, 4, 5, 6, 7}
fmt.Println(arr1)
fmt.Println(arr2)
fmt.Println(arr3)
fmt.Println(arr4)
printArr(arr2)
fmt.Println(arr2)
printArr2(&arr2)
fmt.Println(arr2)
}
- 可通过下划线来省略变量,_代表的是匿名变量
- 不仅range,任何地方都可通过_省略变量
- range意义明确,美观,其他语言无法有类似的
- 数组是值类型——调用进函数时整体会被拷贝进去
- 数组就是数组,是一个值类型,不是头指针之类的
切片的概念
package main
import "fmt"
func updateSlice(s []int) {
s[0] = 100
}
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println("arr[2:6] = ", arr[2:6])
fmt.Println("arr[:6] = ", arr[:6])
fmt.Println("arr[2:] = ", arr[2:])
fmt.Println("arr[:] = ", arr[:])
s1 := arr[2:]
updateSlice(s1)
fmt.Println("s1 = ", s1)
fmt.Println(arr)
s2 := arr[:]
updateSlice(s2)
fmt.Println("s2 = ", s2)
fmt.Println(arr)
fmt.Println("Reslice")
fmt.Println(s2)
s2 = s2[:5]
fmt.Println(s2)
s2 = s2[2:]
fmt.Println(s2)
fmt.Println("Extending slice")
arr[0], arr[2] = 0, 2
s1 = arr[2:6]
s2 = s1[3:5]
fmt.Println("s1 =", s1)
fmt.Printf("s1 = %d, len(s1) = %d, cap(s1) = %d\n", s1, len(s1), cap(s1))
fmt.Println("s2 =", s2)
fmt.Printf("s2 = %d, len(s2) = %d, cap(s2) = %d\n", s2, len(s2), cap(s2))
}
- slice可以向后扩展,不可以向前扩展
- s[i]不可以超越len(s),向后扩展不可以超越底层数组cap(s)
切片的操作
package main
import "fmt"
func printSlice(s []int) {
fmt.Printf("len(s) = %d, cap(s) = %d\n", len(s), cap(s))
}
func main() {
fmt.Println("Creating Slice")
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s1 := arr[2:6]
s2 := s1[3:5]
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Println("s3 = ", s3)
fmt.Printf("len(s3) = %d, cap(s3) = %d\n", len(s3), cap(s3))
fmt.Println("s4 = ", s4)
fmt.Printf("len(s4) = %d, cap(s4) = %d\n", len(s4), cap(s4))
fmt.Println("s5 = ", s5)
fmt.Printf("len(s5) = %d, cap(s5) = %d\n", len(s5), cap(s5))
fmt.Println("arr = ", arr)
var ss []int
for i := 0; i < 100; i++ {
printSlice(ss)
ss = append(ss, 2*i+1)
}
fmt.Println(ss)
ss1 := []int{2, 4, 6, 8}
fmt.Println(ss1)
printSlice(ss1)
ss2 := make([]int, 16)
ss3 := make([]int, 10, 32)
fmt.Printf("%d", ss2)
printSlice(ss2)
fmt.Printf("%d", ss3)
printSlice(ss3)
fmt.Println("Copying Slice")
copy(ss2, ss1)
fmt.Println(ss2)
fmt.Println("Delete elements from slice")
ss2 = append(ss2[:3], ss2[4:]...)
fmt.Println(ss2)
fmt.Println("poping from front")
front := ss2[0]
ss2 = ss2[1:]
fmt.Println("poping from tail")
tail := ss2[len(ss2)-1]
ss2 = ss2[:len(ss2)-1]
fmt.Println(front, tail)
printSlice(ss2)
}
- 添加元素时如果超过cap,系统会重新分配更大的底层数组,原来的数组如果没有继续使用,则会由系统的垃圾回收机制进行回收
- 由于值传递的关系,必须接收append的返回值
- s = append(s, val)
Map
package main
import "fmt"
func main() {
m := map[string]string{
"name": "ccmouse",
"course": "golang",
"site": "imooc",
"quality": "notbad",
}
m1 := make(map[string]int)
var m2 map[string]int
fmt.Println(m, m1, m2)
fmt.Println("traversing map")
for k, v := range m {
fmt.Println(k, v)
}
fmt.Println("getting values")
courseName, ok := m["course"]
fmt.Println(courseName, ok)
if causeName, ok1 := m["cause"]; ok1 {
fmt.Println(causeName)
} else {
fmt.Println("key dose not exist")
}
fmt.Println(m1["a"])
m1["a"]++
fmt.Println(m1["a"])
fmt.Println("delete values")
name, ok2 := m["name"]
fmt.Println(name, ok2)
delete(m, "name")
name, ok2 = m["name"]
fmt.Println(name, ok2)
}
- map[key]value/map[k1]map[k2]value
- 创建:make(map[string]int)
- 获取元素:m[key]
- key不存在时,获得Value类型额初始值
- 用value, ok := m[key]来判断是否存在key
- 用delete来删除一个key
- 使用range遍历key,或者遍历key,value对
- 不保证遍历顺序,如需顺序,需手动对key排序
- 使用len来获得元素的个数
- map使用哈希表,必须可以比较相等
- 除了slice,map,function的内建类型都可以作为key
- struct类型不包含上述字段,也可作为key
map例题(寻找最长不含有重复字符的子串)
package main
import (
"fmt"
)
func longestSubstring(s string) int {
if len(s) == 0 {
return 0
}
m := make(map[byte]int)
maxlengthSubstringIndex := make(map[int]int)
start := 0
maxlength := 0
for i, v := range []byte(s) {
if lasti, ok := m[v]; ok && m[v] >= start {
start = lasti + 1
}
if i-start+1 >= maxlength {
maxlengthSubstringIndex[start] = i
maxlength = i - start + 1
}
m[v] = i
}
for st, e := range maxlengthSubstringIndex {
if (e - st + 1) == maxlength {
fmt.Println(s[st : e+1])
}
}
return maxlength
}
func main() {
example1 := "bbbbb"
example2 := "kwpskkba"
example3 := "abcdcba"
fmt.Println(longestSubstring(example1))
fmt.Println(longestSubstring(example2))
fmt.Println(longestSubstring(example3))
}
- 对于每一个字母x
- m[x]不存在,或者<start,则无需操作
- m[x] >=start,更新start
- 更新m[x],更新maxlength
字符和字符串的处理
package main
import (
"fmt"
"unicode/utf8"
)
func longestSubstring(s string) int {
if len(s) == 0 {
return 0
}
m := make(map[rune]int)
maxlengthSubstringIndex := make(map[int]int)
start := 0
maxlength := 0
for i, v := range []rune(s) {
if lasti, ok := m[v]; ok && m[v] >= start {
start = lasti + 1
}
if i-start+1 >= maxlength {
maxlengthSubstringIndex[start] = i
maxlength = i - start + 1
}
m[v] = i
}
for st, e := range maxlengthSubstringIndex {
if (e - st + 1) == maxlength {
fmt.Println(s[st : e+1])
}
}
return maxlength
}
func main() {
s := "yeah我爱慕课网!"
fmt.Println(len(s))
fmt.Printf("%s\n", []byte(s))
fmt.Printf("%X\n", []byte(s))
for _, b := range []byte(s) {
fmt.Printf("%X ", b)
}
fmt.Println()
for i, ch := range s {
fmt.Printf("(%d %X)", i, ch)
}
fmt.Println()
fmt.Println("rune count:", utf8.RuneCountInString(s))
bytes := []byte(s)
for len(bytes) > 0 {
ch, size := utf8.DecodeRune(bytes)
bytes = bytes[size:]
fmt.Printf("%c ", ch)
}
fmt.Println()
for i, ch := range []rune(s) {
fmt.Printf("(%d %c) ", i, ch)
}
fmt.Println()
example1 := "一二三二一"
example2 := "kwpskkba"
example3 := "我喜欢"
fmt.Println(longestSubstring(example1))
fmt.Println(longestSubstring(example2))
fmt.Println(longestSubstring(example3))
}
- 使用range遍历pos,rune对
- 使用utf8.RuneCountInString获得字符数量
- 使用len获得字节长度
- 使用[]byte获得字节
- Fields,Split,Join
- Contians,Index
- ToLower,ToUpper
- Trim,TrimRight,TrimLeft