摘要:優(yōu)化老代碼的時(shí)候,用到了字典樹。我用寫了一個(gè)字典樹。因?yàn)槭嵌嗖鏄浣Y(jié)構(gòu),可能這兩個(gè)單詞,,需要一個(gè)結(jié)束的標(biāo)識(shí)位。但是應(yīng)該有相關(guān)的文本搜索算法和字典樹相結(jié)合。如果字典樹更新不頻繁,比如地名,字典樹是可以化,保存到中。
優(yōu)化老代碼的時(shí)候,用到了字典樹。我用Java寫了一個(gè)字典樹。分享一下。
先說一下常見的引用場(chǎng)景,單詞匹配,統(tǒng)計(jì)(敏感詞檢測(cè),單詞檢測(cè)),還有輸入提示等等。
下面是代碼了
node節(jié)點(diǎn)代碼
public class Node{ private ListnodeList = new ArrayList<>(); private char word; //這里保存的一個(gè)字符 private int isEnd = 0; //這里是一個(gè)結(jié)束標(biāo)識(shí) public Node(char w){ this.word = w; } public Node(){ } public List getNodeList() { return nodeList; } public void setNodeList(List nodeList) { this.nodeList = nodeList; } public char getWord() { return word; } public void setWord(char word) { this.word = word; } public int getIsEnd() { return isEnd; } public void setIsEnd(int isEnd) { this.isEnd = isEnd; } }
Node節(jié)點(diǎn)重點(diǎn)就是保存的char和isEnd這個(gè)兩個(gè)屬性,這里我保存的是字符串,其實(shí)可以保存成utf8的編碼,防止一些編碼問題。
因?yàn)槭嵌嗖鏄浣Y(jié)構(gòu),可能這兩個(gè)單詞 sad,saddy,需要一個(gè)結(jié)束的標(biāo)識(shí)位。
添加節(jié)點(diǎn)代碼
public void addNode(ListnodeList,char[] word){ List temp = new ArrayList<>(); //遍歷單詞 for (int i=0;i < word.length; i++ ){ //查看子節(jié)點(diǎn) for (int j = nodeList.size(); j >= 0; j--) { //有子節(jié)點(diǎn)并且字相同,則更新nodeList并且跳出循環(huán),檢查下一個(gè)字 if (j > 0 && nodeList.get(j-1).getWord() == word[i]) { nodeList = nodeList.get(j-1).getNodeList(); break; //如果子節(jié)點(diǎn)為零,則說明需要添加新節(jié)點(diǎn) }else if(j == 0 ){ Node n = new Node(word[i]); //判斷是否達(dá)到單詞結(jié)尾,添加標(biāo)志位 if( nodeList.size() == 0 && (i == word.length -1)){ n.setIsEnd(1); } temp = n.getNodeList(); nodeList.add(n); //nodeList賦值給新節(jié)點(diǎn),結(jié)束循環(huán) nodeList = temp; } } } }
這一段需要注意的一點(diǎn)是,我是用了List這個(gè)數(shù)據(jù)結(jié)構(gòu),這個(gè)地方可以優(yōu)化為Map結(jié)構(gòu),Hash表的時(shí)間復(fù)雜度是O(1)。
搜索單詞
public boolean searchNode(ListnodeList,char[] word){ for (int i=0;i < word.length; i++ ){ for (int j = nodeList.size() - 1; j >= 0; j--) { if (nodeList.get(j).getWord() == word[i]) { //單詞處于結(jié)尾,和有標(biāo)志位,則直接返回 if( (i == word.length -1) && nodeList.get(j).getIsEnd() == 1){ return true; } nodeList = nodeList.get(j).getNodeList(); break; } } } return false; }
搜索文本
public boolean searchText(ListnodeList,char[] word){ //記錄頭節(jié)點(diǎn) List head = nodeList; for (int i=0;i < word.length; i++ ){ for (int j = nodeList.size() - 1; j >= 0; j--) { if (nodeList.get(j).getWord() == word[i]) { //搜索文本就不要判斷單詞是否處于結(jié)尾了,查到直接就返回結(jié)果 if( nodeList.get(j).getIsEnd() == 1){ return true; } nodeList = nodeList.get(j).getNodeList(); break; } //當(dāng)節(jié)點(diǎn)沒有子節(jié)點(diǎn),并且程序運(yùn)行到此,將nodeList復(fù)位到頭節(jié)點(diǎn) if(j == 0){ nodeList = head; } } } return false; }
處理敏感詞部分,或者相似功能應(yīng)該做分詞的處理。如果不做分詞處理的,會(huì)出現(xiàn)錯(cuò)誤,比如瑪麗露A。往后再推一個(gè)單詞。
我這里是一個(gè)字一個(gè)字去進(jìn)行順序查找的。但是應(yīng)該有相關(guān)的文本搜索算法和字典樹相結(jié)合。可以提高效率。
我這里實(shí)現(xiàn)的是O(m*n)上面也提到了可以優(yōu)化到O(n),但是也比之前快了不少了。比如輸入提示,比每一次查詢數(shù)據(jù)庫之類的要快很多。如果字典樹更新不頻繁,比如地名,字典樹是可以json化,保存到Redis中。這樣可以給其他語言去使用,而且比一次性查詢數(shù)據(jù)庫,之后再結(jié)構(gòu)化,也是要快一點(diǎn)的。
如果還哪里寫錯(cuò)了,或者有什么更好的優(yōu)化建議,歡迎討論。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/74276.html
摘要:優(yōu)化老代碼的時(shí)候,用到了字典樹。我用寫了一個(gè)字典樹。因?yàn)槭嵌嗖鏄浣Y(jié)構(gòu),可能這兩個(gè)單詞,,需要一個(gè)結(jié)束的標(biāo)識(shí)位。但是應(yīng)該有相關(guān)的文本搜索算法和字典樹相結(jié)合。如果字典樹更新不頻繁,比如地名,字典樹是可以化,保存到中。 優(yōu)化老代碼的時(shí)候,用到了字典樹。我用Java寫了一個(gè)字典樹。分享一下。 先說一下常見的引用場(chǎng)景,單詞匹配,統(tǒng)計(jì)(敏感詞檢測(cè),單詞檢測(cè)),還有輸入提示等等。 下面是代碼了nod...
摘要:查找操作查詢指定單詞是否在字典樹中。將單詞標(biāo)記為當(dāng)前單詞,將根節(jié)點(diǎn)標(biāo)記為當(dāng)前節(jié)點(diǎn),執(zhí)行操作當(dāng)前單詞為空,那么返回,即字典樹中存在該單詞。字典樹的簡(jiǎn)單實(shí)現(xiàn)插入操作查找操作刪除操作具體實(shí)現(xiàn)放在上,可以在這里找到。 原文地址 字典樹介紹 我們經(jīng)常會(huì)在網(wǎng)上輸入一些單詞,一般情況下,當(dāng)我們輸入幾個(gè)字母時(shí),輸入框中會(huì)自動(dòng)彈出以這些字母開頭的單詞供我們選擇,用戶體驗(yàn)非常好。 不過這種自動(dòng)提示功能到底...
摘要:原文地址在簡(jiǎn)單字典樹的實(shí)現(xiàn)一文中,我們以單詞輸入自動(dòng)提示為引子,簡(jiǎn)單介紹了字典樹的實(shí)現(xiàn)。前綴匹配本文講述前綴匹配的字典樹實(shí)現(xiàn)方案。在簡(jiǎn)單字典樹的實(shí)現(xiàn)一文中,我們已經(jīng)實(shí)現(xiàn)了字典樹的基本操作,這里只需要再加上一個(gè)前綴匹配方法即可。 原文地址 在簡(jiǎn)單字典樹(Trie)的實(shí)現(xiàn)一文中,我們以單詞輸入自動(dòng)提示為引子,簡(jiǎn)單介紹了字典樹的實(shí)現(xiàn)。那么,字典樹到底可以用于哪些場(chǎng)合呢? 前綴匹配:給定字典...
摘要:生成樹和最小生成樹的概念設(shè)圖連通,則生成樹包含圖中的所有節(jié)點(diǎn),及條邊的連通圖,一個(gè)圖的生成樹可以有多顆最小生成樹最小權(quán)重生成樹,在生成樹的概念上加一個(gè)限制條件,即生成樹的所有邊的權(quán)值總和最小的樹,最小生成樹也可以有多顆求解最小生成樹的通用 1. 生成樹和最小生成樹的概念 設(shè)圖G(V,E)連通,則生成樹:包含圖G(V,E)中的所有節(jié)點(diǎn),及|V|-1條邊的連通圖,一個(gè)圖的生成樹可以有多顆最...
摘要:另一種高效實(shí)現(xiàn)下面介紹另一種實(shí)現(xiàn),它將字典樹用數(shù)組存儲(chǔ)起來,不僅壓縮了數(shù)組,而且不降低查找效率。這就是雙數(shù)組字典樹。 字典樹的心得體會(huì) 常見的字典樹實(shí)現(xiàn)方法 class Node{ uint node ; uint[] next; }; 或者類似如下結(jié)構(gòu) class Node{ uint node; map n...
閱讀 3433·2021-11-22 09:34
閱讀 1899·2019-08-30 12:53
閱讀 3490·2019-08-28 18:07
閱讀 2977·2019-08-27 10:55
閱讀 2959·2019-08-26 10:12
閱讀 3584·2019-08-23 18:21
閱讀 1338·2019-08-23 14:10
閱讀 1469·2019-08-23 13:04