一、数组
数量写在类型前面
package main
import (
"fmt"
)
func main() {
var arr1 [5] int
arr2 := [3] int {1, 3, 5}
arr3 := [...] int {2, 4, 6, 8, 10}
var grid [4][5] int
fmt.Println(arr1, arr2, arr3, grid)
}
数组的遍历
可通过_省略变量
不仅 range,任何地方都可通过_省略变量
如果只要 i,可写成 for i := range numbers
package main
import (
"fmt"
)
func main() {
arr := [...] int {2, 4, 6, 8, 10}
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
for i, v := range arr {
fmt.Println(i, v)
}
for _, v := range arr {
fmt.Println(v)
}
}
数组是值类型
[10]int 和 [20]int 是不同类型
调用 func f(arr [10]int) 会拷贝数组
在 go 语言中一般不直接使用数组
package main
import (
"fmt"
)
func main() {
var arr1 [5]int
arr2 := [...]int{2, 4, 6, 8, 10}
fmt.Println("printArray(arr1)")
printArray(arr1)
fmt.Println("printArray(arr2)")
printArray(arr2)
fmt.Println("arr1 and arr2")
fmt.Println(arr1, arr2)
}
func printArray(arr [5]int) {
arr[0] = 100
for i, v := range arr {
fmt.Println(i, v)
}
}
二、切片 slice
2.1、切片的概念
slice 本身没有数据,是对底层 array 的一个 view
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])
s1 := arr[2:]
fmt.Println("s1 =", s1)
s2 := arr[:]
fmt.Println("s2 =", s2)
fmt.Println("After updateSlice(s1)")
updateSlice(s1)
fmt.Println(s1)
fmt.Println(arr)
fmt.Println("After updateSlice(s2)")
updateSlice(s2)
fmt.Println(s2)
fmt.Println(arr)
fmt.Println("Reslice")
fmt.Println(s2)
s2 = s2[:5]
fmt.Println(s2)
s2 = s2[2:]
fmt.Println(s2)
}
slice 扩展
package main
import "fmt"
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println("arr =", arr)
s1 := arr[2:6]
s2 := s1[3:5]
fmt.Println("s1 =", s1)
fmt.Println("s2 =", s2)
}
slice 的实现如下图
slice 可以向后扩展,不可以向前扩展
s[i] 不可以超越 len(s),向后扩展不可以超越底层数组 cap(s):cap=capacity容量
package main
import "fmt"
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println("arr =", arr)
s1 := arr[2:6]
s2 := s1[3:5]
fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n",
s1, len(s1), cap(s1))
fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n",
s2, len(s2), cap(s2))
}
2.2、切片的操作
向 slice 添加元素:append(s, val)
添加元素时如果超越 cap,系统会重新分配更大的底层数组
由于值传递的关系,必须接收 append 的返回值
package main
import "fmt"
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println("arr =", arr)
s1 := arr[2:6]
s2 := s1[3:5]
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Println("s3, s4, s5 =", s3, s4, s5)
// s4 and s5 no longer view arr.
fmt.Println("arr =", arr)
}
创建 slice:make 函数
package main
import "fmt"
func main() {
var s []int // Zero value for slice is nil
for i := 0; i < 100; i++ {
printSlice(s)
s = append(s, 2*i+1)
}
fmt.Println(s)
s1 := []int{2, 4, 6, 8}
printSlice(s1)
s2 := make([]int, 12)
s3 := make([]int, 10, 32)
printSlice(s2)
printSlice(s3)
}
func printSlice(s []int) {
fmt.Printf("%v, len=%d, cap=%d\n",
s, len(s), cap(s))
}
复制 slice:copy 函数
package main
import "fmt"
func main() {
s1 := []int{2, 4, 6, 8}
printSlice(s1)
s2 := make([]int, 12)
printSlice(s2)
copy(s2, s1)
printSlice(s2)
}
func printSlice(s []int) {
fmt.Printf("%v, len=%d, cap=%d\n",
s, len(s), cap(s))
}
删除 slice:删除第二个元素
package main
import "fmt"
func main() {
s1 := []int{2, 4, 6, 8}
printSlice(s1)
s1 = append(s1[:1], s1[2:]...)
printSlice(s1)
}
func printSlice(s []int) {
fmt.Printf("%v, len=%d, cap=%d\n",
s, len(s), cap(s))
}
删除 slice:删除头部、删除尾部
package main
import "fmt"
func main() {
s1 := []int{2, 4, 6, 8}
printSlice(s1)
fmt.Println("Popping from front")
front := s1[0]
s1 = s1[1:]
fmt.Println(front)
printSlice(s1)
fmt.Println("Popping from back")
tail := s1[len(s1)-1]
s1 = s1[:len(s1)-1]
fmt.Println(tail)
printSlice(s1)
}
func printSlice(s []int) {
fmt.Printf("%v, len=%d, cap=%d\n",
s, len(s), cap(s))
}
三、Map
3.1、创建
package main
import "fmt"
func main() {
m1 := map[string]string{
"name": "lulubin",
"course": "golang",
"site": "lulublog",
"quality": "notbad",
}
m2 := make(map[string]int) // m2 == empty map
var m3 map[string]int // m3 == nil
fmt.Println("m1=", m1);
fmt.Println("m2=", m2);
fmt.Println("m3=", m3);
}
3.2、获取
key 不存在时,获得 value 类型的初始值
用 value, ok:= m[key] 来判断是否存在 key
package main
import "fmt"
func main() {
m := map[string]string{
"name": "lulubin",
"course": "golang",
"site": "lulublog",
"quality": "notbad",
}
courseName := m["course"]
fmt.Println(`m["course"] =`, courseName)
if causeName, ok := m["cause"]; ok {
fmt.Println(causeName)
} else {
fmt.Println("key 'cause' does not exist")
}
}
3.3、删除
package main
import "fmt"
func main() {
m := map[string]string{
"name": "lulubin",
"course": "golang",
"site": "lulublog",
"quality": "notbad",
}
name, ok := m["name"]
fmt.Printf("m[%q] before delete: %q, %v\n", "name", name, ok)
delete(m, "name")
name, ok = m["name"]
fmt.Printf("m[%q] after delete: %q, %v\n", "name", name, ok)
}
3.4、遍历
使用 range 遍历 key,或者遍历 key, value 对
不保证遍历顺序,如需顺序,需手动对 key 排序
使用 len 获得元素个数
package main
import "fmt"
func main() {
m := map[string]string{
"name": "lulubin",
"course": "golang",
"site": "lulublog",
"quality": "notbad",
}
for k, v := range m {
fmt.Println(k, v)
}
}
3.5、map 的 key
map 使用哈希表,必须可以比较相等
除了 slice, map, function 的内建类型都可以作为 key
Struct 类型不包含上述字段,也可作为 key
3.6、例题
3.6.1、题目
寻找最长不含有重复字符的子串
示例 1:
输入:s = "abcabcbb"
输出:3
解释:因为无重复字符的最长子串是 "abc",所以其长度为 3
示例 2:
输入:s = "bbbbb"
输出:1
解释:因为无重复字符的最长子串是 "b",所以其长度为 1
示例 3:
输入:s = "pwwkew"
输出:3
解释:因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入:s = ""
输出:0
3.6.2、解题思路
对于每一个字母 x
lastOccurred[x] 不存在,或者< start →无需操作
lastOccurred[x] >= start >更新start
更新 lastOccurred[x],更新 maxLength
3.6.3、代码
package main
import "fmt"
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("黑化肥挥发发灰会花飞灰化肥挥发发黑会飞花"))
}
四、字符和字符串处理
4.1、rune
rune 相当于 go 的char
使用 range 遍历 pos, rune 对
使用 utf8.RuneCountInString 获得字符数量
使用 len 获得字节长度
使用 []byte 获得字节
4.2、代码
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Yes我爱鲁鲁博客!" // UTF-8
fmt.Println(s)
for _, b := range []byte(s) {
fmt.Printf("%X ", b)
}
//59 65 73 E6 88 91 E7 88 B1 E9 B2 81 E9 B2 81 E5 8D 9A E5 AE A2 21
fmt.Println()
for i, ch := range s { // ch is a rune
fmt.Printf("(%d %X) ", i, ch)
}
//(0 59) (1 65) (2 73) (3 6211) (6 7231) (9 9C81) (12 9C81) (15 535A) (18 5BA2) (21 21)
fmt.Println()
fmt.Println("Rune count:",
utf8.RuneCountInString(s))
//Rune count: 10
bytes := []byte(s)
for len(bytes) > 0 {
ch, size := utf8.DecodeRune(bytes)
bytes = bytes[size:]
fmt.Printf("%c ", ch)
}
//Y e s 我 爱 鲁 鲁 博 客 !
fmt.Println()
for i, ch := range []rune(s) {
fmt.Printf("(%d %c) ", i, ch)
}
//(0 Y) (1 e) (2 s) (3 我) (4 爱) (5 鲁) (6 鲁) (7 博) (8 客) (9 !)
fmt.Println()
}
4.3、其他字符串操作
Fields、Split、Join
Contains、Index
ToLower、ToUpper
Trim、TrimRight、TrimLeft