go学习写个简单的字典树

232 阅读1分钟

遇到的坑

go中获取字符串长度的问题

`byte等同于uint8,常用来处理ascii字符`

`rune 等同于int32,常用来处理unicode或utf-8字符`

`golang中string``底层是通过``byte``数组实现的。中文字符在unicode下占2个字节,在utf-8编码下占3个字节,而golang默认编码正好是utf-8。`
使用 bytes.Count() 获取、           长度-1
使用 strings.Count() 获取、         长度-1
使用 len() 获取                     字节               
使用 utf8.RuneCountInString() 获取。正常

image.png

字典树

结构

根节点为空,每个根节点都是一个匹配的单词,中间节点也可以是一个单词 image.png

用途
  • 输入提示根据前缀获取匹配的单词
  • 切词看是否是一个单词,根据字典模板判断当前是否是一个单词
  • 词频统计,热点词,可以在数据结构中加入搜索词搜索的次数
实现
  • 搜索当前匹配的位置
  • 根据搜索位置插入
  • 根据搜索位置判断是否匹配
数据结构
type dictTree struct {
	str    rune        //当前的字符
	isDict bool        //是否表示一个单词
	child  []*dictTree //子节点
        //可以有个匹配计数 统计热点词
}
搜索
// 查询字符串位置
func (head *dictTree) search(str string, index int) (*dictTree, int) {
	if head.IsEmpty() || "" == str || index < 0 {
		return nil, -1
	}
	//arrayOfStr := strings.Fields(str)
	oldIndex := index
	for _, c := range head.child {
		for ; index < utf8.RuneCountInString(str); index++ {
			if rune(str[index]) == c.str {
				index++
                                //递归
				return c.search(str, index)
			}
		}
                //匹配不到的时候复位
		index = oldIndex
	}
	return head, index
}
插入
// 插入一个字符串
func (head *dictTree) insert(str string) {
	if str == "" {
		return
	}
	//arrayOfStr := strings.Fields(str)
	current, index := head.search(str, 0)
	for ; index < utf8.RuneCountInString(str); index++ {
		newNode := newDictTree(rune(str[index]), false)
		current.child = append(current.child, newNode)
		current = newNode
	}
        //最后设置属性
	current.isDict = true
}
// 判断是否是单词
func (head *dictTree) check(str string) bool {
	current, index := head.search(str, 0)
	if index == utf8.RuneCountInString(str) && current.isDict {
		return true
	} else {
		return false
	}
}
测试

image.png