记录一下写过的代码,也欢迎各位大佬指正!
使用长度为26的数组实现字典树(存储英文):
package cn.fosu.java;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
class TrieNode {
public char data;
public TrieNode[] children;
public boolean isEndingChar;
public TrieNode(char data) {
this.data = data;
isEndingChar = false;
children = new TrieNode[26];
}
}
public class Trie {
private final TrieNode root = new TrieNode('/');
private TrieNode curr;
public void insert(char[] pattern) {
curr = root;
try {
for (char p : pattern) {
int index = p - 'a';
if (curr.children[index] == null) {
TrieNode newNode = new TrieNode(p);
curr.children[index] = newNode;
}
curr = curr.children[index];
}
curr.isEndingChar = true;
} catch (ArrayIndexOutOfBoundsException ignored) {
}
}
public boolean find(char[] pattern) {
curr = root;
for (char p : pattern) {
int index = p - 'a';
if (curr.children[index] == null) {
return false;
}
curr = curr.children[index];
}
return curr.isEndingChar;
}
public boolean isExist(String str) {
return curr.data == (int) str.charAt(str.length() - 1);
}
public String tips(String str) {
StringBuilder sb = new StringBuilder("提示:");
TrieNode temp;
for (int i = 0; i < 26; ++i) {
temp = curr;
if (temp.children[i] != null) {
sb.append(" ");
sb.append(str);
sb.append(temp.children[i].data);
temp = temp.children[i];
while (!temp.isEndingChar) {
for (int j = 0; j < 26; ++j) {
if (temp.children[j] != null) {
sb.append(temp.children[j].data);
temp = temp.children[j];
break;
}
}
}
}
}
return sb.toString();
}
public char[] transfer(String s) {
char[] temp = new char[s.length()];
for (int i = 0; i < s.length(); ++i) {
temp[i] = s.charAt(i);
}
return temp;
}
public void readFile(String filepath) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filepath));
String str;
while ((str = br.readLine()) != null) {
insert(transfer(str.replaceAll(" ", "")));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Trie t = new Trie();
t.readFile("data/word.txt");
System.out.println("请输入关键词:(输入“:q“退出程序)");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
while (true) {
String str = br.readLine().replaceAll(" ", "");
if (str.equals(":q")) break;
if (!t.find(t.transfer(str))) {
if (t.isExist(str)) {
System.out.println("你可能要找的是:");
System.out.println(t.tips(str));
} else {
System.out.println("没有搜索到相关内容");
}
} else {
System.out.println("你可能要找的是:");
System.out.println(t.tips(str));
}
}
} catch (ArrayIndexOutOfBoundsException | IOException ignored) {
} catch (StringIndexOutOfBoundsException e) {
System.out.println("输入了无关字符");
} finally {
System.out.println("程序已退出...");
}
}
}
使用HashMap实现:
package cn.fosu.java;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
class TrieNodeCN {
public Map<Character, TrieNodeCN> childMap;
public boolean isEnding = false;
public TrieNodeCN() {
childMap = new HashMap<>();
}
}
public class TrieHash {
private final TrieNodeCN root = new TrieNodeCN();
private TrieNodeCN curr;
private StringBuilder prev;
public void insert(String word) {
curr = root;
for (int i = 0; i < word.length(); ++i) {
char c = word.charAt(i);
if (!curr.childMap.containsKey(c)) {
curr.childMap.put(c, new TrieNodeCN());
}
curr = curr.childMap.get(c);
}
curr.isEnding = true;
}
public boolean find(String word) {
prev = new StringBuilder();
curr = root;
for (int i = 0; i < word.length(); ++i) {
char c = word.charAt(i);
if (!curr.childMap.containsKey(c)) {
return false;
}
prev.append(word.charAt(i));
curr = curr.childMap.get(c);
}
return curr.isEnding;
}
public boolean isExist() {
return !curr.childMap.isEmpty();
}
public String tips() {
String pre = prev.toString();
StringBuilder sb = new StringBuilder();
TrieNodeCN temp;
int i = 1;
for (Character key : curr.childMap.keySet()) {
temp = curr.childMap.get(key);
sb.append(i++);
sb.append("、");
sb.append(pre);
sb.append(key);
while (!temp.childMap.isEmpty()) {
if (temp.isEnding) break;
char fk = (char) temp.childMap.keySet().toArray()[0];
sb.append(fk);
temp = temp.childMap.get(fk);
}
sb.append(" ");
}
return sb.toString();
}
public void readFile(String filepath) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filepath));
String str;
while ((str = br.readLine()) != null) {
insert(str.trim());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TrieHash th = new TrieHash();
th.readFile("data/wordCN.txt");
System.out.println("请输入:(输入“:q“退出程序)");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
while (true) {
String str = br.readLine().trim();
if (str.equals(":q")) break;
if (th.find(str)) {
if (th.isExist()) {
System.out.println("你可能要找的是:");
System.out.println(th.tips());
}
} else {
if (th.isExist()) {
System.out.println("你可能要找的是:");
System.out.println(th.tips());
} else {
System.out.println("没有搜索到相关内容");
}
}
}
} catch (ArrayIndexOutOfBoundsException | IOException ignored) {
} catch (StringIndexOutOfBoundsException e) {
System.out.println("输入了无关字符");
} finally {
System.out.println("程序已退出...");
}
}
}