字典树

来源:互联网 发布:java中的compare 编辑:程序博客网 时间:2024/06/05 04:30

关于字典树的解释请看网址:http://www.java3z.com/cwbwebhome/article/article8/83591.html?id=4750

该网址贴出了java实现一个a-z 26个字母的字典树以及一个案例,一定要看这个案例。

</pre>下面是java代码:</p><p>public class Trie {<span style="white-space:pre"></span><span style="white-space:pre"></span>private class TrieNode{<span style="white-space:pre"></span>//内部类,字典树节点类<span style="white-space:pre"></span>private int num;<span style="white-space:pre"></span>//有多少单词通过这个节点,即节点字符出现的次数,也说明了有多少son引用被用到,或者说有多少条被用到的树的边,或者说是该节点的度<span style="white-space:pre"></span>private TrieNode[] son;<span style="white-space:pre"></span>//所有儿子节点<span style="white-space:pre"></span>private boolean isEnd;<span style="white-space:pre"></span>//是不是最后一个节点<span style="white-space:pre"></span>private char val;<span style="white-space:pre"></span>//节点的值<span style="white-space:pre"></span><span style="white-space:pre"></span>TrieNode(){<span style="white-space:pre"></span>num = 1;<span style="white-space:pre"></span>son = new TrieNode[SIZE];<span style="white-space:pre"></span>isEnd = false;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>private int SIZE = 26;<span style="white-space:pre"></span>private TrieNode root;<span style="white-space:pre"></span>//字典树的根<span style="white-space:pre"></span><span style="white-space:pre"></span>Trie(){<span style="white-space:pre"></span>root = new TrieNode();<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>//在字典树中插入一个单词<span style="white-space:pre"></span>public void insert(String str){<span style="white-space:pre"></span><span style="white-space:pre"></span>if(str == null || str.length() == 0)<span style="white-space:pre"></span>return;<span style="white-space:pre"></span><span style="white-space:pre"></span>TrieNode node = root;<span style="white-space:pre"></span>char[] letters = str.toCharArray();<span style="white-space:pre"></span>for(int i = 0, len = str.length(); i< len; i++){<span style="white-space:pre"></span>int pos = letters[i] - 'a';<span style="white-space:pre"></span>if(node.son[pos] == null){<span style="white-space:pre"></span>node.son[pos] = new TrieNode();<span style="white-space:pre"></span>node.son[pos].val = letters[i];<span style="white-space:pre"></span>}else{<span style="white-space:pre"></span>node.son[pos].num++;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>node = node.son[pos];<span style="white-space:pre"></span>//使node指向儿子节点<span style="white-space:pre"></span>}<span style="white-space:pre"></span>node.isEnd = true;<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>// 计算单词前缀的数量<span style="white-space:pre"></span>public int countPrefix(String prefix){<span style="white-space:pre"></span><span style="white-space:pre"></span>if(prefix == null || prefix.length() == 0)<span style="white-space:pre"></span>return -1;<span style="white-space:pre"></span><span style="white-space:pre"></span>TrieNode node = root;<span style="white-space:pre"></span>char[] letters = prefix.toCharArray();<span style="white-space:pre"></span>for(int i = 0, len = prefix.length(); i< len; i++){<span style="white-space:pre"></span>int pos = letters[i] - 'a';<span style="white-space:pre"></span>if(node.son[pos] == null){<span style="white-space:pre"></span>return 0;<span style="white-space:pre"></span>}else{<span style="white-space:pre"></span>node = node.son[pos];<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return node.num;<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>// 在字典树中查找一个完全匹配的单词<span style="white-space:pre"></span>public boolean has(String str){<span style="white-space:pre"></span><span style="white-space:pre"></span>if(str == null || str.length() == 0)<span style="white-space:pre"></span>return false;<span style="white-space:pre"></span><span style="white-space:pre"></span>TrieNode node = root;<span style="white-space:pre"></span>char[] letters = str.toCharArray();<span style="white-space:pre"></span>for(int i = 0, len = str.length(); i< len; i++){<span style="white-space:pre"></span>int pos = letters[i] - 'a';<span style="white-space:pre"></span>if(node.son[pos] != null)<span style="white-space:pre"></span>node = node.son[pos];<span style="white-space:pre"></span>else<span style="white-space:pre"></span>return false;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return node.isEnd;<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>// 前序遍历字典树<span style="white-space:pre"></span>public void preTraverse(TrieNode node){<span style="white-space:pre"></span><span style="white-space:pre"></span>if(node != null){<span style="white-space:pre"></span>System.out.print(node.val + "-");<span style="white-space:pre"></span>for(TrieNode child : node.son){<span style="white-space:pre"></span>preTraverse(child);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>public TrieNode getRoot() {<span style="white-space:pre"></span>return root;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public void setRoot(TrieNode root) {<span style="white-space:pre"></span>this.root = root;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public static void main(String[] args) {<span style="white-space:pre"></span>Trie tree = new Trie();<span style="white-space:pre"></span>String[] strs={<span style="white-space:pre"></span>"banana",<span style="white-space:pre"></span>"band",<span style="white-space:pre"></span>"bee",<span style="white-space:pre"></span>"absolute",<span style="white-space:pre"></span>"acm"<span style="white-space:pre"></span>};<span style="white-space:pre"></span>String[] prefix={<span style="white-space:pre"></span>"ba",<span style="white-space:pre"></span>"b",<span style="white-space:pre"></span>"band",<span style="white-space:pre"></span>"abc"<span style="white-space:pre"></span>};<span style="white-space:pre"></span><span style="white-space:pre"></span>for(String str : strs){<span style="white-space:pre"></span>tree.insert(str);<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>System.out.println(tree.has("abc"));<span style="white-space:pre"></span>tree.preTraverse(tree.getRoot());<span style="white-space:pre"></span>System.out.println();<span style="white-space:pre"></span><span style="white-space:pre"></span>//tree.printAllWords()<span style="white-space:pre"></span>for(String pre : prefix){<span style="white-space:pre"></span>int num = tree.countPrefix(pre);<span style="white-space:pre"></span>System.out.println(pre + " " + num);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}}</p><p></p><p>接下来是把该程序该为C++代码:</p><p><pre name="code" class="cpp">

#include<iostream>
#include<string>
using namespace std;


const int size = 26;


class TrieNode{
public:
int num; //有多少单词通过这个节点,即节点字符出现的次数,也说明了有多少son引用被用到,或者说有多少条被用到的树的边,或者说是该节点的度
TrieNode* son[size];//所有儿子节点的指针
bool isEnd; //是不是最后一个节点,即叶子节点
char val; //节点的值


public:
TrieNode(){
num = 1;
isEnd = false;
// son = new TrieNode[26];//有待商榷
for(int i = 0; i< size; i++)
son[i] = NULL;
}
};


class Trie{
private:
TrieNode* root;


public:
Trie(){
root = new TrieNode();
root->val = '*';//表示根节点的值
}

//在字典树中插入一个单词
void insert(string& str){
if(str == "" || str.length() == 0)
return;

TrieNode* node = root;
const char* letters = str.c_str();
for(size_t i = 0, len = str.length(); i< len; i++){
int pos = *(letters+i) - 'a';
if(node->son[pos] == NULL){
node->son[pos] = new TrieNode();
node->son[pos]->val = *(letters + i);
}else{
node->son[pos]->num ++;
}
node = node->son[pos];
}
node->isEnd = true;
}


// 计算单词前缀的数量
int countPrefix(string& prefix){
if(prefix == "" || prefix.length() == 0)
return -1;


TrieNode* node = root;
const char* letters = prefix.c_str();
for(size_t i = 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;
}


// 在字典树中查找一个完全匹配的单词
bool has(string& str){
if(str == "" || str.length() == 0)
return false;


TrieNode* node = root;
const char* letters = str.c_str();
for(size_t i = 0, len = str.length(); i< len; i++){
int pos = *(letters + i) - 'a';
if(node->son[pos] != NULL)
node = node->son[pos];
else
return false;
}
return node->isEnd;
}


// 前序遍历字典树
void preTraverse(TrieNode* node){
if(node != NULL){
cout << node->val <<"-";
for(int i = 0; i< size; i++){
if(node->son[i] != NULL)
preTraverse(node->son[i]);
}
}
}


TrieNode* getRoot(){
return root;
}
};

int main(){
Trie* tree = new Trie();
string strs[5] = {
"banana",
"band",
"bee",
"absolute",
"acm"
};


string prefix[4]={
"ba",
"b",
"band",
"abc"
};


// for(int i = 0; i< (strs->length()); i++){
// for(int i = 0; i< sizeof(procedureList)/sizeof(string); i++){
for(int i = 0; i< 5; i++){
tree->insert(strs[i]);
}
   
string pre = "abc";
cout << (tree->has(pre)) << endl;


tree->preTraverse(tree->getRoot());
cout<<endl;


//tree.printAllWords()
// for(int i = 0; i< (prefix->length()); i++){
for(int i = 0; i< 4; i++){
int num = tree->countPrefix(prefix[i]);
cout<< prefix[i] << " " << num << endl;
}

return 0;

}

0 0