Trie(前缀树/字典树)
Trie,又经常叫前缀树,字典树等等,是一种多叉树结构。如下图:
基本功能实现:
只记录小写字母,用pass记录有多少字符串经过该节点,end记录有多少字符串以该节点结尾。
- 用数组实现:
#include <iostream> #include <malloc.h> #include <string> using namespace std; typedef struct node{ int pass; int end; struct node* next[26]; } *trieTree; trieTree init() { trieTree t = (trieTree)malloc(sizeof(node)); for (int i = 0; i < 26; i++) t->next[i] = NULL; for (int i = 0; i < 26; i++) t->next[i] = NULL; t->pass = 0; t->end = 0; return t; } void insert(trieTree T,string s) { node *n = T; for (int i = 0; i < s.length(); i++) { int index = s[i] - ‘a‘; if (T->next[index] == NULL) { node *t = init(); T->next[index] = t; } T = T->next[index]; T->pass++; } T->end++; } int find(trieTree T, string s) { node *n = T; for (int i = 0; i < s.length(); i++) { int index = s[i] - ‘a‘; if (T->next[index] == NULL) { return NULL; } T = T->next[index]; } return T->pass; }
- 用STL map实现:
#include <iostream> #include <map> #include <string> using namespace std; class node{ public: int pass; int end; map<char,struct node *>m; }; typedef node* trieTree; trieTree init() { trieTree t = new node; //别的很多人可能初始值给的是1,仔细看insert的代码,这里是没错的 t->pass = 0; t->end = 0; return t; } void insert(trieTree T,string s) { for (int i = 0; i < s.length(); i++) { if (T->m.find(s[i]) == T->m.end()) { node *t = init(); T->m.insert(make_pair(s[i], t)); } T = T->m[s[i]]; T->pass++; } T->end++; } int find(trieTree T, string s) { node *n = T; for (int i = 0; i < s.length(); i++) { if (T->m.find(s[i]) == T->m.end()) { return NULL; } T = T->m[s[i]]; } return T->pass; }
应用:
前缀树典型应用是用于统计,排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计。
它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较。
具体应用主要分为四类:
- 前缀匹配 :HDU 1251:随手练——HDU 1251 统计难题
- 字符串检索 :
- 词频统计 :当使用map内存不够时。
- 字符串排序:Trie树是一棵多叉树,只要先序遍历整棵树,输出相应的字符串便是按字典序排序的结果。
比如给你N 个互不相同的仅由一个单词构成的英文名,让你将它们按字典序从小到大排序输出。
原文地址:https://www.cnblogs.com/czc1999/p/10351808.html
时间: 2024-10-02 20:10:12