字典(前缀)树,用来保存字符集合。
通过建树后 可以快速进行查询相关操作。
此树的特点在于信息在两个节点之间的边上,每条边是一个字符,当一条路径可以构成一个单词的时候,这条路径的最底端(不一定是叶子节点)将会被标记。
例如: 对 ab,abc,c,bd,cd,efg 进行建树
节点是粉色的表示当前从根到当前节点会构成完整的单词。
每个几点最多有26个孩子,因为有26个字母。
以下用数组进行建树及相关操作 其中的sz是每个节点的编号,
#include <iostream> #include <string> using namespace std; #define MAX 10000 #define SIZE 30 class Trie { private: int val[MAX]; int sz; //节点编号 char ch[MAX][SIZE]; //ch[i][j] = k 节点i的第j个孩子的节点为k public: Trie() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } int idx(char c) { return c - 'a'; } void insert(string s, int v) { int node = 0; //节点 int id; for (int i = 0; i < s.size(); i++) { id = idx(s[i]); //这个节点不存在 需要创建 if (!ch[node][id]) { //第node节点的第id个孩子为sz编号 ch[node][id] = sz; memset(ch[node], 0, sizeof(ch[node])); val[sz] = 0; sz++; } node = ch[node][id]; } //表示根到当前节点可以组成一个单词 val[node] = v; } //查询s是否存在于字典树中 bool find(string s) { int node = 0; int id; int k; //当前节点的编号 for (int i = 0; i < s.size(); i++) { id = idx(s[i]); k = ch[node][id]; if (!ch[node][id] && !val[k]) return false; else node = ch[node][id]; } if (val[k] == 1) return true; return false; } }; int main() { Trie trie; int n = 2; string s; for (int i = 0; i < n; i++) { cin >> s; trie.insert(s, 1); } string t; cin >> t; cout << trie.find(t) << endl; system("pause"); return 0; }