# Map

# 一. Map

map声明:map[key的类型][value类型]{初始值}

举例1:

m := map[string]int{
 "one": 1, 
 "two": 2, 
 "three": 3,
}

举例2:

m2 := map[string]int{}
m2["one"] = 1

举例3:使用 make 关键字创建

m3 := make(map[string]int)

举例4:

var m4 map[string]int

Map 元素的访问, 与其他主要编程语言的差异

在访问的 key 不存在时, 返回Value类型的初始值, (举例4中 value类型是int,初始值是0), 不会通过返回 nil

可以通过if判断来判断访问的key是否存在;

if v, ok := m["four"]; ok {
 // 存在
 t.Log("four", v)
} else {
 // 不存在
 t.Log("Not existing")
}

# 二. Map 遍历

遍历模式:

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

如果判断 key 值是否存在?

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

也可以单独使用 k 或者 v

for k := range m1 {
 fmt.Println(k)
}

for _, v := range m1 {
 fmt.Println(v)
}

WARNING

map 中 key 是无序的
go 中是没有 Set 方法的

# 三. 删除某个元素

delete(m, "name")

# 四. 实现 Set

Go 的内置集合中没有 Set 实现, 可以通过 map[type]bool 来实现

  1. 元素的唯一性
  2. 基本操作
  • 添加元素
  • 判断元素是否存在
  • 删除元素
  • 元素个数
func TestMapForSet(t *testing.T) {
 mySet := map[int]bool{}
 mySet[1] = true
 n := 3
 if mySet[n] {
  t.Log("%d is existing", n)
 } else {
  t.Log("%d is not existing", n)
 }
}

# 五. Map例题

剑指 Offer 48. 最长不含重复字符的子字符串。

题目: 请从字符串中找出一个最长的不包含重复字符的子字符串。
示例1: abcabcbb -> abc
示例2: bbbb -> b
示例3: pwwkew -> wke

package main

func lengthOfNonRepeatingSubStr(s string) int{
  lastOccurred := make(map[byte] int)
  start := -1
  maxLength := 0
  // go 语言使用的char类型,是rune(32位的类型),转成byte(8位)
  // 2021.12.3:还不明白 byte 和 rune 的区别?:为什么要转成 byte?
  // 解释:当表示中文的时候,每3个byte表示一个中文,rune相当于go的char,可以把中文的3个byte存到一个rune里,所以遍历时,可以把字符转成rune
  for i, ch := range []rune(s) {
    if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
      start = lastI
    }
    if i - start > maxLength {
      maxLength = i - start
    }
    lastOccurred[ch] = i
  }
  return maxLength
}

func main () {
  fmt.Println(
    lengthOfNonRepeatingSubStr("abcabacab")
  )
  fmt.Println(
    lengthOfNonRepeatingSubStr("bbbbb")
  )
  fmt.Println(
    lengthOfNonRepeatingSubStr("pwwkew")
  )
}