Java中關(guān)于字典樹的算法實(shí)現(xiàn)
字典樹(前綴樹)算法實(shí)現(xiàn)
前言
字典樹,又稱單詞查找樹,是一個(gè)典型的 一對(duì)多的字符串匹配算法?!耙弧敝傅氖且粋€(gè)模式串,“多”指的是多個(gè)模板串。字典樹經(jīng)常被用來統(tǒng)計(jì)、排序和保存大量的字符串。它利用字符串的公共前綴來減少查詢時(shí)間,最大限度地減少無謂的字符串比較。
字典樹有3個(gè)基本性質(zhì):
- 根節(jié)點(diǎn)不包含字符,其余的每個(gè)節(jié)點(diǎn)都包含一個(gè)字符;
- 從根節(jié)點(diǎn)到某一節(jié)點(diǎn),路徑上經(jīng)過的字符連接起來,為該節(jié)點(diǎn)對(duì)應(yīng)的字符串;
- 每個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)包含的字符都不相同。
pass
參數(shù):代表從這個(gè)點(diǎn)經(jīng)過的單詞數(shù)量。root根即就是整棵樹有多少單詞。
end
參數(shù): 代表在這個(gè)點(diǎn)結(jié)束的單詞有幾個(gè)。例如: 上圖有兩個(gè) hello,在o結(jié)點(diǎn)的end參數(shù)就是2。
實(shí)現(xiàn)的基本功能: 增刪查。
算法解析
首先是結(jié)點(diǎn)的參數(shù):
public class Node { public int pass; public int end; public Node[] nexts; //下一個(gè)字母的地址 public Node() { pass = 0; end = 0; nexts = new Node[26]; //這里我們就以小寫字母為例 } }
下面就是基本功能的實(shí)現(xiàn):
import java.util.Scanner; public class Main { public static void main(String[] args) { String[] arr = {"hello", "hello"}; Trie root = new Trie(); for (int i = 0; i < arr.length; i++) { root.addWord(arr[i]); } //root.delWord("hello"); Scanner sc = new Scanner(System.in); String s = sc.nextLine(); if (root.searchWord(s) != 0) { System.out.println("該字典樹有這個(gè)" + s + " 單詞"); } } public static class Node { public int pass; public int end; public Node[] nexts; //下一個(gè)字母的地址 public Node() { pass = 0; end = 0; nexts = new Node[26]; } } public static class Trie { private Node root; public Trie() { root = new Node(); } //增加 public void addWord(String str) { char[] arr = str.toCharArray(); root.pass++; Node node = root; for (char s : arr) { int index = s - 'a'; //以相應(yīng)的ASCII碼值差值,進(jìn)行數(shù)組的下標(biāo)存儲(chǔ) if (node.nexts[index] == null) { node.nexts[index] = new Node(); } node = node.nexts[index]; node.pass++; //經(jīng)過這個(gè)結(jié)點(diǎn),pass就加1 } node.end++; } //刪除 public void delWord(String str) { //刪除之前,應(yīng)該查詢一下這顆樹有沒有這個(gè)單詞 while (searchWord(str) != 0) { char[] arr = str.toCharArray(); Node node = root; node.pass--; for (int i = 0; i < str.length(); i++) { int index = arr[i] - 'a'; node = node.nexts[index]; node.pass--; } node.end--; } } //查找 public int searchWord(String str) { if (str == null) { return 0; } char[] arr = str.toCharArray(); Node node = root; for (int i = 0; i < str.length(); i++) { int index = arr[i] - 'a'; if (node.nexts[index] == null) { return 0; } node = node.nexts[index]; } return node.end; //返回最后那一個(gè)結(jié)點(diǎn)的end值即可 } } }
到此這篇關(guān)于Java中關(guān)于字典樹的算法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java 字典樹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Java并發(fā)包中線程池ThreadPoolExecutor
ThreadPoolExecutor是Java語言對(duì)于線程池的實(shí)現(xiàn)。線程池技術(shù)使線程在使用完畢后不回收而是重復(fù)利用。如果線程能夠復(fù)用,那么我們就可以使用固定數(shù)量的線程來解決并發(fā)問題,這樣一來不僅節(jié)約了系統(tǒng)資源,而且也會(huì)減少線程上下文切換的開銷2021-06-06SpringMVC中的@RequestMapping注解解析
這篇文章主要介紹了SpringMVC中的@RequestMapping注解解析,SpringMVC使用@RequestMapping注解為控制器指定可以處理哪些?URL?請(qǐng)求,在控制器的類定義及方法定義處都可標(biāo)注@RequestMapping,需要的朋友可以參考下2023-12-12Spring?Boot整合持久層之JdbcTemplate多數(shù)據(jù)源
持久層是JavaEE中訪問數(shù)據(jù)庫的核心操作,SpringBoot中對(duì)常見的持久層框架都提供了自動(dòng)化配置,例如JdbcTemplate、JPA 等,MyBatis 的自動(dòng)化配置則是MyBatis官方提供的。接下來分別向讀者介紹Spring Boot整合這持久層技術(shù)中的整合JdbcTemplate2022-08-08Java輕松實(shí)現(xiàn)批量插入或刪除Excel行列操作
在職場生活中,對(duì)Excel工作表的行和列進(jìn)行操作是非常普遍的需求,下面小編就來和大家介紹一下如何在Java中完成批量插入、刪除行和列的操作吧2023-10-10java String、Json對(duì)象與byte數(shù)組轉(zhuǎn)換方式
這篇文章主要介紹了java String、Json對(duì)象與byte數(shù)組轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07詳解mybatis插入數(shù)據(jù)后返回自增主鍵ID的問題
這篇文章主要介紹了mybatis插入數(shù)據(jù)后返回自增主鍵ID詳解,本文通過場景分析示例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07