1-实现单词插入并统计插入次数
2-实现查找单词是否存于字母查找树中
3-实现自动补全提醒
注意:
1-只支持全小写字母单词
2-查询时间复杂度为log(h),h为单词长度
3-插入时间复杂度为log(h),h为单词长度
4-空间复杂度小于所有字母个数
结点代码:
package bin.tree.trie;
/**字母查找树节点
* @author 牵手无奈
* date:2015-9-2
*
*/
public class MyTrie {
private static final int LETTER_SIZE=26;
private char letter;//字母
private int count;//单词插入次数
private MyTrie[] nextLetter = new MyTrie[LETTER_SIZE];//26叉树
public MyTrie() {
super();
}
public MyTrie(char letter) {
super();
this.letter = letter;
this.count=0;
}
public void initialNext(){
for(int i=0;i<LETTER_SIZE;i++){
char temp = (char) (i+97);
nextLetter[i]=new MyTrie(temp);
}
}
public MyTrie getNexTrie(int index){
if(index>=0&&index<LETTER_SIZE){
return nextLetter[index];
}else{
try {
throw new MyIndexOutOfBoundException();
} catch (MyIndexOutOfBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public void setNexTrie(int index,MyTrie myTrie){
if(index>=0&&index<LETTER_SIZE){
nextLetter[index] = myTrie;
}else{
try {
throw new MyIndexOutOfBoundException();
} catch (MyIndexOutOfBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public char getLetter() {
return letter;
}
public void setLetter(char letter) {
this.letter = letter;
}
public MyTrie[] getNextLetter() {
return nextLetter;
}
public void setNextLetter(MyTrie[] nextLetter) {
this.nextLetter = nextLetter;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void countAddOne() {
this.count++;
}
}
操作字母查找树代码:
package bin.tree.trie;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**操作字母查找树
* @author 牵手无奈
* date:2015-9-2
*
*/
public class TrieManage {
private MyTrie head;
/**插入单词操作
* @param word
* @return
*/
public boolean insertWord(String word){
if(head==null){
head=new MyTrie();
}
if(isWord(word)){
MyTrie p = head;
for(int i=0;i<word.length();i++){
char letter = word.charAt(i);
int index = letter-97;
//p=p.getNexTrie(index);
if(p.getNexTrie(index)==null){
p.setNexTrie(index, new MyTrie(letter));
}
p=p.getNexTrie(index);
}
p.countAddOne();
return true;
}
return false;
}
/**返回不匹配字母下标,
* @param word
* @return -1表示输入字符串有误,返回下标等于字符串长度表示完全匹配
*/
public MyTrie checkMaxMatch(String word){
if(isWord(word)){
MyTrie p = head;
for(int i=0;i<word.length();i++){
char letter = word.charAt(i);
int index = letter-97;
p=p.getNexTrie(index);
if(p==null){
return null;
}
}
return p;
}
return null;
}
/**检查输入单词是否在字母查找树中
* @param word
* @return
*/
public boolean check(String word){
MyTrie result = checkMaxMatch(word);
if(result!=null &&result.getCount()>0)
return true;
return false;
}
/**检查输入单词在字母树中出现的次数
* @param word
* @return
*/
public int checkCount(String word){
MyTrie result = checkMaxMatch(word);
if(result!=null &&result.getCount()>0)
return result.getCount();
return 0;
}
/**自动补全,列出可以匹配的单词
* @param key
* @return
*/
public List<String> autoComplete(String key){
List<String> result = new ArrayList<>();
MyTrie p = checkMaxMatch(key);
//开始先序遍历
listAllLast(p, result, new StringBuffer());
return result;
}
/**先序遍历剩下的部分
* @param p
* @param list
* @param oneWord
*/
public void listAllLast(MyTrie p,List<String> list,StringBuffer oneWord){
if(!checkNext(p)){
list.add(oneWord.toString());
oneWord.replace(0,oneWord.length(), "");
}else{
MyTrie[] nextList = p.getNextLetter();
for(MyTrie trie:nextList){
if(trie!=null){
oneWord.append(trie.getLetter());
listAllLast(trie, list, oneWord);
}
}
}
}
/**检查当前结点是否是叶子结点
* @param trie
* @return
*/
public boolean checkNext(MyTrie trie){
MyTrie[] nextList = trie.getNextLetter();
for(MyTrie t:nextList){
if(t!=null)
return true;
}
return false;
}
/**判断输入的字符串是不是全是小写字母
* @param word
* @return
*/
public static boolean isWord(String word){
Pattern p = Pattern.compile("[a-z]+");
Matcher matcher = p.matcher(word);
return matcher.matches();
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
InputStream in = TrieManage.class.getClassLoader().getResourceAsStream("resources/words.txt");
InputStreamReader inr = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inr);
String line;
TrieManage tm = new TrieManage();
while( (line= reader.readLine())!=null){
System.out.println(line);
String[] array = line.split("[ ]+");
for(String element:array){
tm.insertWord(element);
}
}
InputStreamReader testInr = new InputStreamReader(System.in);
BufferedReader testReader = new BufferedReader(testInr);
do {
String str = testReader.readLine();
if(str.equals("end")){
break;
}else{
System.out.println("--------------"+str+"----------------");
//System.out.println(tm.check(str));
//System.out.println(tm.checkCount(str));
tm.autoComplete(str);
System.out.println("--------------------------------");
}
} while (true);
}
}
本程序测试时从文件读入数据