Trie树模板

字典(前缀)树,用来保存字符集合。

通过建树后 可以快速进行查询相关操作。


此树的特点在于信息在两个节点之间的边上,每条边是一个字符,当一条路径可以构成一个单词的时候,这条路径的最底端(不一定是叶子节点)将会被标记。

例如:  对 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;
}


猜你喜欢

转载自blog.csdn.net/a673786103/article/details/80297552