golang学习笔记——内建容器

数组
package main

import (
	"fmt"
)

func printArr(arr [5]int) {
	arr[0] = 100
	for i, v := range arr { //go语言特性之一,也是其他语言没有的——range;可以用_来略过其中一个变量
		fmt.Println(i, v)
	}
}

func printArr2(arr *[5]int) {
	arr[0] = 100
	for i, v := range arr { //go语言特性之一,也是其他语言没有的——range;可以用_来略过其中一个变量
		fmt.Println(i, v)
	}
}

func main() {

	var arr1 []int                        //空数组
	var arr4 [3]int                       //数组内初值都为0
	arr2 := [5]int{1, 2}                  //除了已赋值的,其余都为0
	arr3 := [...]int{1, 2, 3, 4, 5, 6, 7} //根据给的数值分配数组长度,也可以不需要...

	fmt.Println(arr1)
	fmt.Println(arr2)
	fmt.Println(arr3)
	fmt.Println(arr4)

	// printArr(arr1) //[]int和[5]int不是同一类型
	printArr(arr2)
	// printArr(arr3) //arr3的数组长度跟[5]int不一致,不是同一类型
	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]) //[2 3 4 5]
	fmt.Println("arr[:6] = ", arr[:6])   //[0 1 2 3 4 5]
	fmt.Println("arr[2:] = ", arr[2:])   //[0 1 2 3 4 5]
	fmt.Println("arr[:] = ", arr[:])     //[0 1 2 3 4 5]

	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) //[100 1 100 3 4 5 6 7]
	s2 = s2[:5]
	fmt.Println(s2) //[100 1 100 3 4]
	s2 = s2[2:]
	fmt.Println(s2) //[100 3 4]

	//slice的扩展
	fmt.Println("Extending slice")
	arr[0], arr[2] = 0, 2
	s1 = arr[2:6]
	s2 = s1[3:5]
	fmt.Println("s1 =", s1)                                                   //s1 =  [2 3 4 5]
	fmt.Printf("s1 = %d, len(s1) = %d, cap(s1) = %d\n", s1, len(s1), cap(s1)) //s1 = [2 3 4 5], len(s1) = 4, cap(s1) = 6;cap为底层数组
	fmt.Println("s2 =", s2)                                                   //s2 = [5, 6]
	fmt.Printf("s2 = %d, len(s2) = %d, cap(s2) = %d\n", s2, len(s2), cap(s2)) //s2 = [5 6], len(s2) = 2, cap(s2) = 3

}

  • 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)
	// s6 := append(s5, 13)
	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))
	// s4 and s5 no longer view arr
	fmt.Println("arr = ", arr)

	var ss []int
	for i := 0; i < 100; i++ {
		printSlice(ss)
		ss = append(ss, 2*i+1) //cap不够会自行增长,增长为2倍
	}
	fmt.Println(ss)

	ss1 := []int{2, 4, 6, 8}
	fmt.Println(ss1)
	printSlice(ss1)

	ss2 := make([]int, 16)
	ss3 := make([]int, 10, 32) //第三个参数可给切片定义cap大小
	fmt.Printf("%d", ss2)
	printSlice(ss2)
	fmt.Printf("%d", ss3)
	printSlice(ss3)

	fmt.Println("Copying Slice")
	copy(ss2, ss1)
	fmt.Println(ss2) //[2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0]

	fmt.Println("Delete elements from slice")
	ss2 = append(ss2[:3], ss2[4:]...)
	fmt.Println(ss2) //[2 4 6 0 0 0 0 0 0 0 0 0 0 0 0]

	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() {

	// map是一个hash map,是无序的
	m := map[string]string{
		"name":    "ccmouse",
		"course":  "golang",
		"site":    "imooc",
		"quality": "notbad",
	}

	m1 := make(map[string]int) //空map, m1 == empty map
	var m2 map[string]int      //空map, m2 == nil
	fmt.Println(m, m1, m2)

	fmt.Println("traversing map")
	//由于map是无序的,所以遍历后打印出来的数据是不定顺序的
	for k, v := range m {
		fmt.Println(k, v)
	}

	fmt.Println("getting values")
	courseName, ok := m["course"]
	fmt.Println(courseName, ok) // 打印golang,返回True,存在于该map里面
	if causeName, ok1 := m["cause"]; ok1 {
		fmt.Println(causeName) // 打印"",存在于该map里面
	} else {
		fmt.Println("key dose not exist")
	}

	fmt.Println(m1["a"]) //返回初始零值 zero value
	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的双指针记录起来,作为输出最长不重复子字符串的判定条件
			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的双指针记录起来,作为输出最长不重复子字符串的判定条件
			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)) //rune count: 10

	bytes := []byte(s)
	for len(bytes) > 0 {
		ch, size := utf8.DecodeRune(bytes)
		// fmt.Println(size)
		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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值