关于字典树
字典树是什么,到wiki或者百度百科看一下就可以了,从名字也可以想象得到,这里我就不把定义再打一遍了,从网上找了一个实现,然后自己做了一个实现,这里记录一下。
字典树有几种具体的实现方式,有基于hash的,有基于平衡树的,还有二级字典树等。
字典树是典型的用空间来换时间的算法。
字典树主要的方法就是插入和查找
字典树又称为Trie。
字典树在ACM中使用比较多,所以常常有同学写好了相关的模板,到时候就可以直接来套用了。
http://www.cnblogs.com/Knuth/archive/2009/09/08/1562612.html
但是这个代码的实现要求和我的要求不一样。如果我输入3344,那我查找3,其返回值为1,这和我的要求不同。
1 //字典树模板
2 #include <iostream>
3 using namespace std;
4 const int kind=26;
5 struct node
6 {
7 int i,count;
8 node *next[kind];
9 node()
10 {
11 count=1;
12 for(i=0;i<kind;i++)
13 next[i]=NULL;
14 }
15 };
16 void insert(node *root,char *word)
17 {
18 int i=0,branch;
19 node *local=root;
20 if(local==NULL)
21 {
22 local=new node();
23 root=local;
24 }
25 while(word[i])
26 {
27 branch=word[i]-'a';
28 if(local->next[branch])
29 local->next[branch]->count++;
30 else
31 local->next[branch]=new node();
32 i++;
33 local=local->next[branch];
34 }
35 }
36 int search(node *root,char *word)
37 {
38 int i=0,branch,ans;
39 node *local=root;
40
41 if(local==NULL)
42 return 0;
43 while(word[i])
44 {
45 branch=word[i]-'a';
46 if(!local->next[branch])
47 return 0;
48 i++;
49 local=local->next[branch];
50 ans=local->count;
51 }
52 return ans;
53 }
54 int main()
55 {
56 char str[12];
57 node *root=new node;
58 while(gets(str) && strcmp(str,""))
59 insert(root,str);
60 while(scanf("%s",str)!=EOF)
61 printf("%d\n",search(root,str));
62 return 0;
63 }
2 #include <iostream>
3 using namespace std;
4 const int kind=26;
5 struct node
6 {
7 int i,count;
8 node *next[kind];
9 node()
10 {
11 count=1;
12 for(i=0;i<kind;i++)
13 next[i]=NULL;
14 }
15 };
16 void insert(node *root,char *word)
17 {
18 int i=0,branch;
19 node *local=root;
20 if(local==NULL)
21 {
22 local=new node();
23 root=local;
24 }
25 while(word[i])
26 {
27 branch=word[i]-'a';
28 if(local->next[branch])
29 local->next[branch]->count++;
30 else
31 local->next[branch]=new node();
32 i++;
33 local=local->next[branch];
34 }
35 }
36 int search(node *root,char *word)
37 {
38 int i=0,branch,ans;
39 node *local=root;
40
41 if(local==NULL)
42 return 0;
43 while(word[i])
44 {
45 branch=word[i]-'a';
46 if(!local->next[branch])
47 return 0;
48 i++;
49 local=local->next[branch];
50 ans=local->count;
51 }
52 return ans;
53 }
54 int main()
55 {
56 char str[12];
57 node *root=new node;
58 while(gets(str) && strcmp(str,""))
59 insert(root,str);
60 while(scanf("%s",str)!=EOF)
61 printf("%d\n",search(root,str));
62 return 0;
63 }
如果是英文字母的dictionary tree,那就是一个26叉树。
如果是数字的dictionary tree,那是一个10叉树。
我自己实现的(其实就是修改了一下),是针对数字的。
1 #include <iostream>
2 #include <fstream>
3 #include <string>
4 using namespace std;
5
6 #define max_num 10
7
8 ifstream randfile("random.txt");
9 //ofstream sortedfile("sorted.txt");
10
11 struct node
12 {
13 bool is_word ;
14 node *next[max_num];
15 node()
16 {
17 is_word = false;
18 for(int i = 0;i<max_num;i++)
19 next[i] = NULL;
20 }
21 };
22
23 class Trie
24 {
25 public:
26
27 node *root;
28
29 Trie(){root = NULL;}
30
31 bool search(const string str)
32 {
33 node *location = root;
34 for(int i = 0;i<str.length();i++)
35 {
36 if(location->next[str[i]-'0'] == NULL)
37 return false;
38 location = location->next[str[i]-'0'];
39 }
40 return location->is_word;
41 };
42
43 void insert(const string str)
44 {
45 if(root == NULL)
46 root = new node;
47 node *location = root;
48 for(int i = 0;i<str.length();i++)
49 {
50 int site = str[i] - '0';
51 if(location->next[site] == NULL)
52 {
53 location->next[site] = new node;
54 location = location->next[site];
55 }
56 else
57 location = location->next[site];
58 }
59 location->is_word = true;
60 };
61
62 bool del(const string str)
63 {
64 node *location = root;
65 for(int i = 0;i<str.length();i++)
66 {
67 if(location->next[str[i]-'0'] == NULL)
68 return false;
69 location = location->next[str[i]-'0'];
70 }
71 if(location->is_word)
72 location->is_word = false;
73 else
74 return false;
75 return true;
76 }
77 };
78
79 int main()
80 {
81 Trie trie;
82 string str;
83 while(cin>>str && str!="end")
84 {
85 trie.insert(str);
86 }
87 while(cin>>str)
88 {
89 if(trie.search(str))
90 {
91 cout<<"find the str "<<str<<endl;
92 }
93 else
94 {
95 cout<<"cannot find"<<endl;
96 }
97 }
98 return 0;
99 }
2 #include <fstream>
3 #include <string>
4 using namespace std;
5
6 #define max_num 10
7
8 ifstream randfile("random.txt");
9 //ofstream sortedfile("sorted.txt");
10
11 struct node
12 {
13 bool is_word ;
14 node *next[max_num];
15 node()
16 {
17 is_word = false;
18 for(int i = 0;i<max_num;i++)
19 next[i] = NULL;
20 }
21 };
22
23 class Trie
24 {
25 public:
26
27 node *root;
28
29 Trie(){root = NULL;}
30
31 bool search(const string str)
32 {
33 node *location = root;
34 for(int i = 0;i<str.length();i++)
35 {
36 if(location->next[str[i]-'0'] == NULL)
37 return false;
38 location = location->next[str[i]-'0'];
39 }
40 return location->is_word;
41 };
42
43 void insert(const string str)
44 {
45 if(root == NULL)
46 root = new node;
47 node *location = root;
48 for(int i = 0;i<str.length();i++)
49 {
50 int site = str[i] - '0';
51 if(location->next[site] == NULL)
52 {
53 location->next[site] = new node;
54 location = location->next[site];
55 }
56 else
57 location = location->next[site];
58 }
59 location->is_word = true;
60 };
61
62 bool del(const string str)
63 {
64 node *location = root;
65 for(int i = 0;i<str.length();i++)
66 {
67 if(location->next[str[i]-'0'] == NULL)
68 return false;
69 location = location->next[str[i]-'0'];
70 }
71 if(location->is_word)
72 location->is_word = false;
73 else
74 return false;
75 return true;
76 }
77 };
78
79 int main()
80 {
81 Trie trie;
82 string str;
83 while(cin>>str && str!="end")
84 {
85 trie.insert(str);
86 }
87 while(cin>>str)
88 {
89 if(trie.search(str))
90 {
91 cout<<"find the str "<<str<<endl;
92 }
93 else
94 {
95 cout<<"cannot find"<<endl;
96 }
97 }
98 return 0;
99 }
可以拿这个代码来试试10亿整数中查找重复数的问题。这里我就不试了。