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

Java實(shí)現(xiàn)前綴樹詳解

 更新時(shí)間:2023年04月27日 09:25:58   作者:允歆辰丶  
Java實(shí)現(xiàn)前綴樹(Trie樹)是一種樹形數(shù)據(jù)結(jié)構(gòu),用于字符串的存儲(chǔ)和查找,適用于大量字符串的快速匹配。通過(guò)將字符串拆分為字符序列,依次構(gòu)建樹形結(jié)構(gòu),將每個(gè)字符串的字符依次存儲(chǔ)在樹的節(jié)點(diǎn)上,實(shí)現(xiàn)高效的字符串匹配

一.前綴樹

1.什么是前綴樹

字典樹(Trie樹)是一種樹形數(shù)據(jù)結(jié)構(gòu),常用于字符串的存儲(chǔ)和查找。字典樹的核心思想是利用字符串之間的公共前綴來(lái)節(jié)省存儲(chǔ)空間和提高查詢效率。它是一棵多叉樹,每個(gè)節(jié)點(diǎn)代表一個(gè)字符串的前綴,從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)的路徑組成一個(gè)字符串。

字典樹的根節(jié)點(diǎn)不包含字符,每個(gè)子節(jié)點(diǎn)代表一個(gè)字符,從根節(jié)點(diǎn)到任意一個(gè)節(jié)點(diǎn)所經(jīng)過(guò)的路徑上的字符連接起來(lái)即為該節(jié)點(diǎn)所代表的字符串。每個(gè)節(jié)點(diǎn)可以存儲(chǔ)一個(gè)或多個(gè)字符串,通常使用一個(gè)標(biāo)志來(lái)標(biāo)記一個(gè)節(jié)點(diǎn)代表的字符串是否存在。當(dāng)需要在一組字符串中查找某個(gè)字符串時(shí),可以利用字典樹來(lái)實(shí)現(xiàn)高效的查找操作。

2.前綴樹的舉例

例如對(duì)字符串?dāng)?shù)組{"goog","google","bai","baidu","a"}建立前綴樹,此時(shí)我們可以很清晰的看到前綴樹的一些特征:

  • 根結(jié)點(diǎn)不保存字符
  • 前綴樹是一顆多叉樹
  • 前綴樹的每個(gè)節(jié)點(diǎn)保存一個(gè)字符
  • 具有相同前綴的字符串保存在同一條路徑上
  • 字符串的尾處相應(yīng)的在前綴樹上也有結(jié)束的標(biāo)志

二.前綴樹的實(shí)現(xiàn)

力扣上的208題就是實(shí)現(xiàn)前綴樹:力扣

1.前綴樹的數(shù)據(jù)結(jié)構(gòu)

在寫代碼的時(shí)候,我偏向于用哈希表來(lái)存儲(chǔ)結(jié)點(diǎn)的信息,有的也可以用數(shù)組來(lái)存儲(chǔ)結(jié)點(diǎn)的信息,本質(zhì)上都是一樣的

public class Trie {
    Map<Character, Trie> next;
    boolean isEnd;
    public Trie() {
        this.next = new HashMap<>();
        this.isEnd = false;
    }
    public void insert(String word) {
    }
    public boolean search(String word) {
        return false;
    }
    public boolean startsWith(String prefix) {
        return false;
    }
}

2.插入字符串

    public void insert(String word) {
        Trie trie = this;//獲得根結(jié)點(diǎn)
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null) {//當(dāng)前結(jié)點(diǎn)不存在
                trie.next.put(c, new Trie());//創(chuàng)建當(dāng)前結(jié)點(diǎn)
            }
            trie = trie.next.get(c);//得到字符c的結(jié)點(diǎn),繼續(xù)向下遍歷
        }
        trie.isEnd = true;
    }

3.查找字符串

    public boolean search(String word) {
        Trie trie = this;//獲得根結(jié)點(diǎn)
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null) {//當(dāng)前結(jié)點(diǎn)不存在
                return false;
            }
            trie = trie.next.get(c);//得到字符c的結(jié)點(diǎn),繼續(xù)向下遍歷
        }
        return trie.isEnd;
    }

4.查找前綴

    public boolean startsWith(String prefix) {
        Trie trie = this;//獲得根結(jié)點(diǎn)
        for (char c : prefix.toCharArray()) {
            if (trie.next.get(c) == null) {//當(dāng)前結(jié)點(diǎn)不存在
                return false;
            }
            trie = trie.next.get(c);//得到字符c的結(jié)點(diǎn),繼續(xù)向下遍歷
        }
        return true;
    }

接下來(lái)是力扣上關(guān)于前綴樹的一些題目

三.詞典中最長(zhǎng)的單詞

1.題目描述

給出一個(gè)字符串?dāng)?shù)組words 組成的一本英語(yǔ)詞典。返回words 中最長(zhǎng)的一個(gè)單詞,該單詞是由words詞典中其他單詞逐步添加一個(gè)字母組成。

若其中有多個(gè)可行的答案,則返回答案中字典序最小的單詞。若無(wú)答案,則返回空字符串。

力扣:力扣

2.問題分析

這是一道典型的前綴樹的問題,但是這一題有一些特殊的要求,返回的答案是:

1.最長(zhǎng)的單詞

2.這個(gè)單詞由其他單詞逐步構(gòu)成

3.長(zhǎng)度相同返回字典序小的

因此我們需要對(duì)前綴樹的相關(guān)代碼進(jìn)行修改,把字符串一一插入的代碼還是不改變的,主要修改的是查找的代碼,應(yīng)該在 trie.next.get(c) == null在增加一個(gè)判斷為false的條件,就是每一個(gè)結(jié)點(diǎn)都應(yīng)該有一個(gè)標(biāo)志true,表示每個(gè)節(jié)點(diǎn)都存在一個(gè)單詞,最終一步步構(gòu)成最長(zhǎng)的單詞(葉子結(jié)點(diǎn)的單詞)

3.代碼實(shí)現(xiàn)

class Solution {
    public String longestWord(String[] words) {
        Trie trie = new Trie();
        for (String word : words) {
            trie.insert(word);
        }
        String longest = "";
        for (String word : words) {
            if (trie.search(word)) {
                if (word.length() > longest.length() || ((word.length() == longest.length()) && (word.compareTo(longest) < 0))) {
                    longest = word;
                }
            }
        }
        return longest;
    }
}
class Trie {
    Map<Character, Trie> next;
    boolean isEnd;
    public Trie() {
        this.next = new HashMap<>();
        this.isEnd = false;
    }
    public void insert(String word) {
        Trie trie = this;//獲得根結(jié)點(diǎn)
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null) {//當(dāng)前結(jié)點(diǎn)不存在
                trie.next.put(c, new Trie());//創(chuàng)建當(dāng)前結(jié)點(diǎn)
            }
            trie = trie.next.get(c);//得到字符c的結(jié)點(diǎn),繼續(xù)向下遍歷
        }
        trie.isEnd = true;
    }
    public boolean search(String word) {
        Trie trie = this;//獲得根結(jié)點(diǎn)
        for (char c : word.toCharArray()) {
            if (trie.next.get(c) == null || !trie.next.get(c).isEnd) {//當(dāng)前結(jié)點(diǎn)不存在
                return false;
            }
            trie = trie.next.get(c);//得到字符c的結(jié)點(diǎn),繼續(xù)向下遍歷
        }
        return trie.isEnd;
    }
}

到此這篇關(guān)于Java實(shí)現(xiàn)前綴樹詳解的文章就介紹到這了,更多相關(guān)Java前綴樹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java基于websocket協(xié)議與netty實(shí)時(shí)視頻彈幕交互實(shí)現(xiàn)

    Java基于websocket協(xié)議與netty實(shí)時(shí)視頻彈幕交互實(shí)現(xiàn)

    本文主要介紹了Java基于websocket協(xié)議與netty實(shí)時(shí)視頻彈幕交互實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Elasticsearch?Recovery索引分片分配詳解

    Elasticsearch?Recovery索引分片分配詳解

    這篇文章主要為大家介紹了關(guān)于Elasticsearch的Recovery索引分片分配詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2022-04-04
  • 詳解Java?Unsafe如何花式操作內(nèi)存

    詳解Java?Unsafe如何花式操作內(nèi)存

    C++可以動(dòng)態(tài)的分類內(nèi)存,而java并不能這樣,是不是java就不能操作內(nèi)存呢,其實(shí)是有其他辦法可以操作內(nèi)存的,下面就一起看看Unsafe是如何花式操作內(nèi)存的吧
    2023-08-08
  • Spring大白話之三級(jí)緩存如何解決循環(huán)依賴問題

    Spring大白話之三級(jí)緩存如何解決循環(huán)依賴問題

    Spring通過(guò)三級(jí)緩存(singletonObjects、earlySingletonObjects、singletonFactories)解決單例循環(huán)依賴,三級(jí)緩存使用Lambda表達(dá)式提前暴露bean的早期引用,確保在遞歸調(diào)用時(shí)能夠正確獲取對(duì)象實(shí)例,避免死循環(huán)
    2025-02-02
  • Mybatis實(shí)現(xiàn)批量操作8種小結(jié)

    Mybatis實(shí)現(xiàn)批量操作8種小結(jié)

    本文對(duì)Mybatis的五種批處理方式進(jìn)行了性能測(cè)試,包括批量新增和批量修改,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • java list 比較詳解及實(shí)例

    java list 比較詳解及實(shí)例

    這篇文章主要介紹了java list 比較詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java中的原生post請(qǐng)求方式

    Java中的原生post請(qǐng)求方式

    這篇文章主要介紹了Java中的原生post請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Java中==與equals()及hashcode()三者之間的關(guān)系詳解

    Java中==與equals()及hashcode()三者之間的關(guān)系詳解

    最近也是在讀Hollis的《深入理解Java核心技術(shù)》里面一節(jié)講到了equals()和hashcode()的關(guān)系,對(duì)于這個(gè)高頻面試點(diǎn),咱們需要認(rèn)真理清一下幾者之間的關(guān)系
    2022-10-10
  • java 微信隨機(jī)紅包算法代碼實(shí)例

    java 微信隨機(jī)紅包算法代碼實(shí)例

    這篇文章主要介紹了java 微信隨機(jī)紅包算法的相關(guān)資料,并附實(shí)例代碼,需要的朋友可以參考下
    2016-10-10
  • 基于Java回顧之反射的使用分析

    基于Java回顧之反射的使用分析

    本篇文章是對(duì)Java反射的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論

南郑县| 中卫市| 桓台县| 新泰市| 台中市| 武强县| 南木林县| 绥中县| 加查县| 长宁县| 宜兴市| 汕尾市| 乐清市| 长宁县| 淅川县| 淳安县| 郴州市| 丹寨县| 浦江县| 公主岭市| 三原县| 贞丰县| 大兴区| 耒阳市| 淮阳县| 湖南省| 株洲县| 历史| 民丰县| 尖扎县| 龙海市| 昌图县| 清涧县| 和顺县| 黎川县| 泰来县| 南岸区| 德兴市| 南宁市| 虎林市| 广德县|