最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go語言數(shù)據(jù)結(jié)構(gòu)之前綴樹Trie

 更新時間:2022年05月17日 10:35:03   作者:??呆呆燦????  
這篇文章主要介紹了go語言數(shù)據(jù)結(jié)構(gòu)之前綴樹Trie,文章圍繞主題展開詳細內(nèi)容介紹,具有一定得參考價值,需要的小伙伴可以參考一下

介紹

Trie樹:又稱為單詞查找樹,是一種樹形結(jié)構(gòu),可以應(yīng)用于統(tǒng)計字符串,會在搜索引擎系統(tǒng)中用于對文本的詞頻統(tǒng)計,下圖是一個Trie樹的結(jié)構(gòu),同時它也是在插入數(shù)時的一個順序圖.

流程

  • 首先應(yīng)該先創(chuàng)建一個結(jié)構(gòu)體,里面保存的是每一個節(jié)點的信息
  • 初始化根節(jié)點,根節(jié)點應(yīng)該初始化啥?啥也不用初始化,給個空就好看上圖
  • 插入:串轉(zhuǎn)字符數(shù)組;遍歷數(shù)組,如果下一個節(jié)點為空,創(chuàng)建,則繼續(xù)遍歷
  • 查找:串轉(zhuǎn)字符數(shù)組,遍歷如何所有字符都在樹里面存在,并則最后一個字符Node中的end不為零,就視為存在
  • 刪除: 字符串轉(zhuǎn)數(shù)組,遍歷數(shù)組,在樹上找到對應(yīng)的字符,path-1

代碼

type Node struct {
	path     int
	end      int
	children [26]*Node
}

在這個結(jié)構(gòu)體里面有一個path,它的作用是啥呢?當有經(jīng)過此字符的時候這個path就加一

end又是干啥的呢?當一個單詞的詞尾是這個字符的時候end這個值就加一,就代表著這個字符做為一個單詞的結(jié)尾

children是保存的啥呢?這個里面當然是保存的子節(jié)點啦,不用多說了叭~~~

初始化

func main() {
	list := &Node{path: 0, end: 0}
}

初始化根節(jié)點,上面說過根節(jié)點里面是不用保存數(shù)據(jù)的,這個我就把里面的參數(shù)初始化成0,當然也可以不用初始化里面的參數(shù),children這里就沒有創(chuàng)建出來,因為下面我就要開始插入的操作了

插入

/*
 * 插入數(shù)據(jù)
*/
func insertTrie(str string, root *Node) {
	if len(str) == 0 {
		return
	}
	tempNode := root
	for _, value := range str {
		if tempNode.children[value-'a'] == nil {
			tempNode.children[value-'a'] = &Node{path: 0, end: 0}
		}
		tempNode = tempNode.children[value-'a']
		tempNode.path++
	}
	tempNode.end++
}

在插入之前先說一點:在傳入的參數(shù)中,str我傳入前我將其轉(zhuǎn)換成了小寫的,當然也可以轉(zhuǎn)換成大寫或者是大小寫都有的

插入之前先對字符串進行了一個判空的處理,如果為空就return了,在整個過程中,對字符串進行了遍歷,像我在流程中那樣說的將字符串轉(zhuǎn)成字符數(shù)組,是應(yīng)該這樣操作,但是我發(fā)現(xiàn)在golang中可以直接對一個字符串進行了遍歷,或許將語言換成了Java就需要將其轉(zhuǎn)成字符數(shù)組了

for循環(huán)里面if判斷時為什么數(shù)組的下標要用value-'a'這個東西來表示?可以想像一下,一個節(jié)點的children里面有26個子元素,比如這里的vlaue是b,那么就相當于是b-a,就是b的ASCII碼減去a的ASCII碼,這個就得到的是1

索引字符
0a
1b
2c

當當前的字符在數(shù)組里面沒有對應(yīng)的數(shù)據(jù)的時候創(chuàng)建一個就好,如果有的時候只要將當前數(shù)組的下標交給臨時變量tempNode就好,所經(jīng)過字符的path加1,將最后一個字符所對應(yīng)的end加1,將其標記為一個此字符是一個單詞的結(jié)尾即可.

查找

/*
 *查找數(shù)據(jù)
*/
func searchStr(str string,root *Node) bool {
	if len(str) == 0{
		return false
	}
	tempNode := root
	for _,value := range str{

		if tempNode.children[value - 'a'] == nil{
			return false
		}
		tempNode = tempNode.children[value - 'a']
	}
	if tempNode.end != 0{
		return true
	}
	return false
}

同樣,在查找數(shù)據(jù)的時候也是將需要查找的字符串和前綴樹的ROOT傳入,字符串的判空處理也是必做的,這個里面的tempNode可以有也可以沒有,我寫tempNode可以是說是我的一個編碼的習慣,同樣,在查找單詞的時候也是要遍歷這個字符串(在插入的時候我就已經(jīng)解釋過了我這里為啥和流程中寫的不一樣,沒有把字符串轉(zhuǎn)成字符數(shù)組),在for循環(huán)里面第一個if如果第一個字符沒有在前綴樹中找到,那么就視為所要查找的字符串沒有出現(xiàn)在這個前綴樹里面,則將當前的字符節(jié)點交給臨時變量tempNode,當整個循環(huán)遍歷完成之后,也就說明我要查找的字符串中的每一個字符都在這顆前綴樹里面并連續(xù)著.這個時候如果最后一個單詞的end屬性為大于0的一個數(shù),那么這個要查找的字符串就一定在這顆前綴樹里面,返回true

findstr

統(tǒng)計以XXX開頭的單詞個數(shù)

這個前綴樹很強大,上面的解釋也說到過,可以對文本的統(tǒng)計

strArgs:=[]string{"qQYgMU","FFpdCl","nyyJmh","XJCebb","OrCiHb","xvDdzZ","nyCebF","hi","hello","nyyJmn"}

在前綴樹里面插入了這個數(shù)組里面的字符串,我現(xiàn)在要統(tǒng)計以n開頭的單詞有幾個?如何處理呢?

這里就用到了在結(jié)構(gòu)體中定義的Path屬性了,在插入的時候說過當有一個字符經(jīng)過這個path就會加1,所以我只需要找到所要查找前綴的最后一個單詞拿到了它的path屬性就可以知道以這個字符串開頭的單詞有幾個

/*
 *查找以XX開頭的數(shù)據(jù)有幾個
*/
func searchPrefixCount(str string,root *Node) int{
	if len(str) == 0{
		return -1
	}
	tempNode := root
	for _,value := range str{
		if tempNode.children[value - 'a'] == nil {
			return 0
		}
		tempNode = tempNode.children[value - 'a']
		return tempNode.path
	}
	return -1
}

刪除數(shù)據(jù)

刪除數(shù)據(jù)的時候同樣也是要遍歷字符串,不過在此之前應(yīng)該先查找一次這顆樹里面有沒有要刪除的字符串,如果沒有就直接return就好

/*
 * 刪除數(shù)據(jù)
*/
func delStr(str string,root *Node) bool {
	if len(str) == 0{
		return false
	}
	if !searchStr(strings.ToLower(str),root) {
		return false
	}
	tempNode := root
	for _,value := range str{
		if tempNode.children[value - 'a'].path > 1 {
			tempNode.children[value - 'a'].path--
			tempNode = tempNode.children[value - 'a']
		}else{
			tempNode.children[value - 'a'] = nil
			return true
		}
	}
	return false
}

path是當有字符經(jīng)過的時候加一,那么在刪除數(shù)據(jù)的時候只要查找到字符將這個字符串所經(jīng)過的字符的path減1, 我這里還加了一個else,當path等于1的時候也就是說明當前所要刪除的字符串是最后一個經(jīng)過此字符的字符串,這里直接將其置空,等系統(tǒng)回收就好了

到此這篇關(guān)于go語言數(shù)據(jù)結(jié)構(gòu)之前綴樹Trie的文章就介紹到這了,更多相關(guān)go 前綴樹內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解go-zero如何實現(xiàn)令牌桶限流

    詳解go-zero如何實現(xiàn)令牌桶限流

    令牌桶算法既能夠?qū)⑺械恼埱笃骄植嫉綍r間區(qū)間內(nèi),又能接受服務(wù)器能夠承受范圍內(nèi)的突發(fā)請求,因此是目前使用較為廣泛的一種限流算法,本文就來看看go-zero如何實現(xiàn)令牌桶限流的吧
    2023-08-08
  • 重學Go語言之運算符與控制結(jié)構(gòu)詳解

    重學Go語言之運算符與控制結(jié)構(gòu)詳解

    對于任何編程語言來說,運算符和控制結(jié)構(gòu)都算是最基礎(chǔ)的知識了,既然是基礎(chǔ),當然非常有必要學習,因此在這篇文章中我們就來討論一下
    2023-02-02
  • Golang 內(nèi)存模型詳解(一)

    Golang 內(nèi)存模型詳解(一)

    這篇文章主要介紹了Golang 內(nèi)存模型詳解(一),本文講解了Go內(nèi)存模型interface、,需要的朋友可以參考下
    2014-10-10
  • Go結(jié)合反射將結(jié)構(gòu)體轉(zhuǎn)換成Excel的過程詳解

    Go結(jié)合反射將結(jié)構(gòu)體轉(zhuǎn)換成Excel的過程詳解

    這篇文章主要介紹了Go結(jié)合反射將結(jié)構(gòu)體轉(zhuǎn)換成Excel的過程詳解,大概思路是在Go的結(jié)構(gòu)體中每個屬性打上一個excel標簽,利用反射獲取標簽中的內(nèi)容,作為表格的Header,需要的朋友可以參考下
    2022-06-06
  • 一文探索Go語言中的內(nèi)存對齊

    一文探索Go語言中的內(nèi)存對齊

    在 Go 語言中,內(nèi)存對齊是一個經(jīng)常被忽略但非常重要的概念,本文將通過一個簡單的例子來探討 Go 語言中的內(nèi)存對齊機制,感興趣的可以了解下
    2024-11-11
  • Go各時間字符串使用解析

    Go各時間字符串使用解析

    這篇文章主要介紹了Go各時間字符串使用解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • golang?JSON技巧小結(jié)

    golang?JSON技巧小結(jié)

    本文介紹了在Go語言中使用JSON時的一些小技巧,包括如何將字符串轉(zhuǎn)換為數(shù)字、臨時忽略空字段、臨時添加額外字段、粘合兩個struct、改名struct字段、支持不同類型的數(shù)字,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Go 值傳遞與引用傳遞的方法

    Go 值傳遞與引用傳遞的方法

    這篇文章主要介紹了Go 值傳遞與引用傳遞的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • golang實現(xiàn)圖像驗證碼的示例代碼

    golang實現(xiàn)圖像驗證碼的示例代碼

    這篇文章主要為大家詳細介紹了如何利用golang實現(xiàn)簡單的圖像驗證碼,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-10-10
  • Go官方工具鏈用法詳解

    Go官方工具鏈用法詳解

    Go官方工具鏈工具要求所有的Go源代碼文件必須以.go后綴結(jié)尾。這里,我們假設(shè)一個最簡單的Go程序放在hello.go的文件中,下面通過示例代碼給大家介紹Go官方工具鏈用法簡介,需要的朋友可以參考下
    2021-10-10

最新評論

汉寿县| 翁牛特旗| 八宿县| 江门市| 北安市| 易门县| 都昌县| 洛川县| 崇文区| 砀山县| 大姚县| 清流县| 五莲县| 名山县| 普宁市| 桑日县| 河间市| 特克斯县| 山西省| 正阳县| 岱山县| 民县| 梁平县| 从化市| 十堰市| 东光县| 台江县| 绍兴县| 抚宁县| 博白县| 邓州市| 盘锦市| 云阳县| 青浦区| 饶平县| 蛟河市| 井研县| 北碚区| 民勤县| 南通市| 西贡区|