字典树
2016-03-27 20:59
330 查看
代码实现
Java
packagecom.suning.search.test.tree.trie; public class Trie{ private int SIZE=26; private TrieNode root;//字典树的根 Trie(){//初始化字典树 root=new TrieNode(); } private class TrieNode{//字典树节点 private int num;//有多少单词通过这个节点,即节点字符出现的次数 private TrieNode[] son;//所有的儿子节点 private boolean isEnd;//是不是最后一个节点 private char val;//节点的值 TrieNode(){ num=1; son=new TrieNode[SIZE]; isEnd=false; } } //建立字典树 public void insert(String str){//在字典树中插入一个单词 if(str==null||str.length()==0){ return; } TrieNode node=root; char[]letters=str.toCharArray(); for(inti=0,len=str.length();i<len;i++){ int pos=letters[i]-'a'; if(node.son[pos]==null){ node.son[pos]=newTrieNode(); node.son[pos].val=letters[i]; }else{ node.son[pos].num++; } node=node.son[pos]; } node.isEnd=true; } //计算单词前缀的数量 public int countPrefix(Stringprefix){ if(prefix==null||prefix.length()==0){ return-1; } TrieNode node=root; char[]letters=prefix.toCharArray(); for(inti=0,len=prefix.length();i<len;i++){ int pos=letters[i]-'a'; if(node.son[pos]==null){ return 0; } else{ node=node.son[pos]; } } return node.num; } //打印指定前缀的单词 public String hasPrefix(String prefix) { if (prefix == null || prefix.length() == 0) { return null; } TrieNode node = root; char[] letters = prefix.toCharArray(); for (int i = 0, len = prefix.length(); i < len; i++) { int pos = letters[i] - 'a'; if (node.son[pos] == null) { return null; } else { node = node.son[pos]; } } preTraverse(node, prefix); return null; } // 遍历经过此节点的单词. public void preTraverse(TrieNode node, String prefix) { if (!node.isEnd){ for (TrieNode child : node.son) { if (child!=null){ preTraverse(child, prefix+child.val); } } return; } System.out.println(prefix); } //在字典树中查找一个完全匹配的单词. public boolean has(Stringstr){ if(str==null||str.length()==0){ return false; } TrieNode node=root; char[]letters=str.toCharArray(); for(inti=0,len=str.length();i<len;i++){ intpos=letters[i]-'a'; if(node.son[pos]!=null){ node=node.son[pos]; }else{ return false; } } return node.isEnd; } //前序遍历字典树. public void preTraverse(TrieNodenode){ if(node!=null){ System.out.print(node.val+"-"); for(TrieNodechild:node.son){ preTraverse(child); } } } public TrieNode getRoot(){ return this.root; } public static void main(String[]args){ Trietree=newTrie(); String[]strs={"banana","band","bee","absolute","acm",}; String[]prefix={"ba","b","band","abc",}; for(Stringstr:strs){ tree.insert(str); } System.out.println(tree.has("abc")); tree.preTraverse(tree.getRoot()); System.out.println(); //tree.printAllWords(); for(Stringpre:prefix){ int num=tree.countPrefix(pre); System.out.println(pre+""+num); } } }
C语言
#define MAX 26//字符集大小 typedef struct TrieNode { int nCount;//记录该字符出现次数 struct TrieNode* next[MAX]; }TrieNode; TrieNode Memory[1000000]; int allocp=0; /*初始化*/ void InitTrieRoot(TrieNode* *pRoot) { *pRoot=NULL; } /*创建新结点*/ TrieNode* CreateTrieNode() { int i; TrieNode *p; p=&Memory[allocp++]; p->nCount=1; for(i=0;i<MAX;i++) { p->next[i]=NULL; } return p; } /*插入*/ void InsertTrie(TrieNode* *pRoot,char *s) { inti,k; TrieNode*p; if(!(p=*pRoot)) { p=*pRoot=CreateTrieNode(); } i=0; while(s[i]) { k=s[i++]-'a';//确定branch if(!p->next[k]) p->next[k]=CreateTrieNode(); p->next[k]->nCount++; p=p->next[k]; } } //查找 int SearchTrie(TrieNode* *pRoot,char *s) { TrieNode *p; int i,k; if(!(p=*pRoot)) { return0; } i=0; while(s[i]) { k=s[i++]-'a'; if(p->next[k]==NULL) return 0; p=p->next[k]; } return p->nCount; }
C++
#include<cstring> #include<iostream> #include<conio.h> usingnamespacestd; namespacetrie { template<classT,size_tCHILD_MAX> /* ParameterT:Typeofreserveddata. ParameterCHILD_MAX:Sizeofarryofpointerstochildnode. */ structnod { Treserved; nod<T,CHILD_MAX>*child[CHILD_MAX]; nod() { memset(this,0,sizeof*this); } ~nod() { for(unsignedi=0;i<CHILD_MAX;i++) deletechild[i]; } voidTraversal(char*str,unsignedindex) { unsignedi; for(i=0;i<index;i++) cout<<str[i]; cout<<'\t'<<reserved<<endl; for(i=0;i<CHILD_MAX;i++) { if(child[i]) { str[index]=i; child[i]->Traversal(str,index+1); } } return; } }; template<classT,size_tCHILD_MAX=127> /* ParameterT:Typeofreserveddata. ParameterCHILD_MAX:Sizeofarryofpointerstochildnode. */ classtrie { private: nod<T,CHILD_MAX>root; public: nod<T,CHILD_MAX>*AddStr(char*str); nod<T,CHILD_MAX>*FindStr(char*str); boolDeleteStr(char*str); voidTraversal() { charstr[100]; root.Traversal(str,0); } }; template<classT,size_tCHILD_MAX> nod<T,CHILD_MAX>*trie<T,CHILD_MAX>::AddStr(char*str) { nod<T,CHILD_MAX>*now=&root; do { if(now->child[*str]==NULL) now->child[*str]=newnod<T,CHILD_MAX>; now=now->child[*str]; }while(*(++str)!='\0'); returnnow; } template<classT,size_tCHILD_MAX> nod<T,CHILD_MAX>*trie<T,CHILD_MAX>::FindStr(char*str) { nod<T,CHILD_MAX>*now=&root; do { if(now->child[*str]==NULL) returnNULL; now=now->child[*str]; }while(*(++str)!='\0'); returnnow; } template<classT,size_tCHILD_MAX> booltrie<T,CHILD_MAX>::DeleteStr(char*str) { nod<T,CHILD_MAX>**nods=newnod<T,CHILD_MAX>*[strlen(str)]; intsnods=1; nod<T,CHILD_MAX>*now=&root; nods[0]=&root; do { if(now->child[*str]==NULL) returnfalse; nods[snods++]=now=now->child[*str]; }while(*(++str)!='\0'); snods--; while(snods>0) { for(unsignedi=0;i<CHILD_MAX;i++) if(nods[snods]->child[i]!=NULL) returntrue; deletenods[snods]; nods[--snods]->child[*(--str)]=NULL; } returntrue; } } intmain() { //TestProgram trie::trie<int>tree; while(1) { cout<<"1foraddastring"<<endl; cout<<"2forfindastring"<<endl; cout<<"3fordeleteastring"<<endl; cout<<"4fortraversal"<<endl; cout<<"5forexit"<<endl; charstr[100]; switch(getch()) { case'1': cin.getline(str,100); cout<<"Thisstinghasexistedfor"<<tree.AddStr(str)->reserved++<<"times."<<endl; break; case'2': cin.getline(str,100); trie::nod<int,127>*find; find=tree.FindStr(str); if(!find) cout<<"Nofound."<<endl; else cout<<"Thisstinghasexistedfor"<<find->reserved<<"times."<<endl; break; case'3': cin.getline(str,100); cout<<"Theactionis"<<(tree.DeleteStr(str)?"Successful.":"Unsuccessful.")<<endl; break; case'4': tree.Traversal(); break; case'5': return0; } } return0; }
相关文章推荐
- Spring 容器IOC的初始化过程
- 剑指offer-面试题12:打印1到最大的n位数
- 数据库各种连接的区别
- 数据库各种连接的区别
- Zoj 3537 Cake (DP最优三角形剖分)
- iOS Xib文件详解
- 巴萨教父克鲁伊夫去世&西班牙黄金一代谢幕的一点感想
- SQL SERVER 中 GO 的用法2
- Java笔记---初试云服务器
- 数据库的数据类型
- Android之xml文档中的命名空间
- java内存分配与参数配置
- HDU 1195 Open the Lock (BFS 剪枝)
- Python1————安装
- MySql服务器安装
- 学习javaEE每一天2016.3.27
- Linux进程管理工具top/htop/glances/dstat的使用
- Bzoj 2346: [Baltic 2011]Lamp dijkstra,堆
- [杂七杂八-iOS]个人总结3.27
- struct、union的内存分配