ARST打卡第162周[162/521]

Algorithm

lc890_查找和替换模式

思路: 应该就是简单的建立映射,然后如果有现存的映射就看看是不是一样的,不是的话就返回错误就行了

因为自己的map操作出错了,发现range是Unicode是rune类型,str[i]是utf-8类型,然后看了答案,
发现还要反向映射. 才发现自己的思路不够完备,才明白双射

暴露自己go的初学者的一些错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
func findAndReplacePattern(words []string, pattern string) []string {
var tmp map[rune]byte
var ans []string
for _, word := range(words) {
word_ok := true
for i, c := range(word) {
//cannot use c (type rune) as type byte in map index
// 需要定以为rune
value, ok := tmp[c]
if ok {
if value != pattern[i] {
word_ok = false
break
}
} else {
// panic: assignment to entry in nil map
// 需要:= make(map[rune]byte) 或者 := map[rune]byte{} 进行地址分配
// 同为引用类型的slice,在使用append 向nil slice追加新元素就可以,原因是append方法在底层为slice重新分配了相关数组让nil slice指向了具体的内存地址
tmp[c] = pattern[i]
}
}
if word_ok {
ans = append(ans, word)
}
}

return ans
}

官网正解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func match(word, pattern string) bool {
mp := map[rune]byte{}
for i, x := range word {
y := pattern[i]
if mp[x] == 0 {
mp[x] = y
} else if mp[x] != y { // word 中的同一字母必须映射到 pattern 中的同一字母上
return false
}
}
return true
}

func findAndReplacePattern(words []string, pattern string) (ans []string) {
for _, word := range words {
if match(word, pattern) && match(pattern, word) {
ans = append(ans, word)
}
}
return
}

Review

https://pkg.go.dev/github.com/syndtr/goleveldb/leveldb#DB.Close

leveldb的close和iterators并发不安全,要注意

Tips

一个LevelDB的Go封装

Share

golang类型断言理解[go语言圣经]