Contents

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语言圣经]