这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记。
后端关键问题
-
支持用户自定义关键词过滤
-
支持"相关搜索"功能,自动给出可能的关联条目(字典树)
-
实现关联度算法,能够把关联度高的信息优先展示
-
支持搜索图片
- 用户输入纯文本,根据纯文本搜索出关联的图片数据。
- 图片搜索结果以略缩图展示,支持点击打开原图
-
支持以图搜图
-
用户上传一张图片,系统能理解图片内容,然后搜索出关联的图片
-
前缀树用于支持"相关搜索"功能,自动给出可能的关联条目和实现关联度算法。
package main
import (
"fmt"
)
//数据节点;存储数据:数据值、是否结束标志位、下一个节点指针
type TNode struct {
Data byte
IsWord bool
Next map[byte]*TNode
}
//根节点,存储数据为:1、字符串个数;2、数据节点map序列
type TNRoot struct {
Len int
Node map[byte]*TNode
}
func CreateTire() TNRoot {
tn := make(map[byte]*TNode)
//创建节点的时候,需要将node赋值
tRoot := TNRoot{
Len: 0,
Node: tn, //todo 技巧:需要赋值,不然后续没有办法操作
}
return tRoot
}
func (tn *TNRoot) insert(str string) {
cur := tn.Node
for i := 0; i < len(str); i++ {
if cur[str[i]] == nil {
newNode := &TNode{
Data: str[i],
IsWord: false,
Next: make(map[byte]*TNode), //TODO 技巧:下一个节点需要实例化,不然是空,后续无法操作。
}
cur[str[i]] = newNode
}
if i == len(str)-1 {
cur[str[i]].IsWord = true
}
cur = cur[str[i]].Next
}
tn.Len++
}
func (tn *TNRoot) isExist(str string) bool {
if tn.Node == nil {
return false
}
cur := tn.Node
var res []byte
for i := 0; i < len(str); i++ {
if cur[str[i]] == nil { //如果比较的数据不存在,直接返回
return false
}
res = append(res, cur[str[i]].Data)
fmt.Println("res", string(res))
// fmt.Println("11", cur[str[i]].Next)
mp := cur[str[i]].Next
for k, v := range mp {
fmt.Println(k, v.Data)
}
fmt.Println("--", cur[str[i]].Data, str[i])
if cur[str[i]].Data != str[i] {
return false
}
if i == len(str)-1 { //判断最后一个比较的字符是否是结束标志位
if cur[str[i]].IsWord == true {
return true
}
}
cur = cur[str[i]].Next
}
return false
}
func (tn *TNRoot) search(str string) []string {
heights := make([]string, 20)
if tn.Node == nil {
return heights
}
cur := tn.Node
var res []byte
j := 0
for i := 0; i < len(str); i++ {
if cur[str[i]] == nil { //如果比较的数据不存在,直接返回
return heights
}
// res = append(res, cur[str[i]].Data)
res = append(res, cur[str[i]].Data)
if cur[str[i]].Data != str[i] {
return heights
}
if i == len(str)-1 { //判断最后一个比较的字符是否是结束标志位
if cur[str[i]].IsWord == true {
heights[j] = string(res)
j++
}
cur = cur[str[i]].Next
break
}
cur = cur[str[i]].Next
}
mp := cur
stk := make([]byte, 2000)
tt := 0
for k, v := range mp {
tt += 1
stk[tt] = v.Data
fmt.Println(k, v.Data)
}
// for {
// if tt <= 0 {
// break
// }
// }
return heights
}
func main() {
// heights := make([]string, 20)
// heights[0] = "222"
// fmt.Println("11", heights)
tire := CreateTire()
tire.insert("中文")
tire.insert("中文期刊")
tire.insert("中文胡刊")
tire.insert("中国")
// fmt.Println(tire.search("中"))
tire.insert("hello")
tire.insert("hel")
// fmt.Println(tire.isExist("中文"))
fmt.Println(tire.search("中文"))
// fmt.Println(tire.isExist("中国"))
// fmt.Println(tire.isExist("hel"))
// fmt.Println(tire.isExist("hell"))
// fmt.Println(tire.isExist("hello"))
// fmt.Println("tire树的字符串数量:", tire.Len)
}