标签:单词 mem blog ptr 失败 lag col 隐式 字符
http://hihocoder.com/problemset/problem/1014
(1)数据结构
cnt:记录词典中所有单词经过该节点的次数
flag:标识是否构成以该节点结尾的单词
ptr:指向子节点的指针数组,假设字符集是小写英文字母,ptr[0]!=NULL隐式地表示该节点指向的下一节点对应字符‘a‘
根节点不包含字符,其余每个节点只包含一个字符
(2)插入单词
待插入的字符串word,指针p指向根节点,下标i指向word[0]
若字符串为空,不用处理;
否则,检查word[i]对应的指针p->ptr[word[i]-‘a‘]是否为空;(记该指针为pNext)
若pNext为空,说明这个字符是第一次在树中出现,为该节点开辟一个新内存,并让pNext指向该新节点;
若pNext不为空,说明该字符在树中的节点已经建过了,令p = pNext即可;
把当前p所指的节点的cnt加1
重复以上过程,word中所有字符都处理完。
PS:最后,若p->cnt!=0,说明以p指向的节点字符是一个单词的尾部字符。可令p->flag=true。
对于长度为n的单词,插入单词的时间复杂度为O(n)。
(3)查询单词(查询前缀)
待查询单词prefix(若该prefix是一个完整单词,用布尔变量isWord标识它)
指针p指向根节点,下标i指向prefix[0]
若单词为空,不用处理;(以空串为前缀的单词数量为0)
否则,依次匹配每个prefix[i]
若p->ptr[prefix[i]-‘a‘]为空,说明不存在以prefix为前缀的单词
若p->ptr[prefix[i]-‘a‘]非空,继续i+1位置的下一次匹配,若直到匹配完prefix中所有字符,这个过程都没有断定匹配失败,也就是匹配成功,最终p指向树中节点的字符就是prefix的尾部字符。
PS:最后,若p->flag为true,说明prefix是一个完整单词。
对于长度为n的单词,查询单词的时间复杂度同样为O(n)。
(4)实现代码
1 class Trie 2 { 3 private: 4 int cnt; 5 bool flag; 6 Trie* ptr[26]; 7 public: 8 Trie() 9 { 10 cnt = 0, flag = false; 11 memset(ptr,0,sizeof(ptr)); //NULL 12 } 13 14 void add(const string& word) 15 { 16 if(word == "") return; 17 Trie* p = this; 18 for(int i = 0; i < word.size(); ++i) 19 { 20 int c = word[i] - ‘a‘; 21 if(p->ptr[c] == NULL) 22 p->ptr[c] = new Trie; 23 p = p->ptr[c]; 24 ++p->cnt; 25 } 26 if(p->cnt) 27 p->flag = true; 28 } 29 30 int query(const string& prefix, bool& isWord) 31 { 32 isWord = false; 33 if(prefix == "")return 0; 34 Trie* p = this; 35 for(int i = 0; i < prefix.size(); ++i) 36 { 37 int c = prefix[i] - ‘a‘; 38 if(p->ptr[c] == NULL) 39 return 0; 40 else 41 p = p->ptr[c]; 42 } 43 44 if(p->flag) isWord = true; 45 return p->cnt; 46 } 47 48 };
标签:单词 mem blog ptr 失败 lag col 隐式 字符
原文地址:http://www.cnblogs.com/junjie_x/p/7674336.html