1、
哈希樹的變種。典型應用是用於統計,排序和保存大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。
根節點不包含字符,除根節點外每一個節點都只包含一個字符; 從根節點到某一節點,路徑上經過的字符連接起來,爲該節點對應的字符串; 每個節點的所有子節點包含的字符都不相同。
如果將指針變量指向一個已開闢過的,即已有的空間,就不需要重新開闢內存空間了,只有需要開闢的時候纔開闢內存空間
https://blog.csdn.net/faihung/article/details/90648217 int *q;只有地址,沒有內存空間。這個地址是隨機地址。
像下面這種分配好的就不用new
///////////////////////////////int *p 只能指向別人的內存不能在棧上自動分配了(*p=1是錯的)
class Solution {
public:
class Tree{
public:
bool word_here=false;
Tree* v[26]={nullptr};
static void insert(Tree* t, const string &s){
for(char c:s){
if(!t->v[c-'a'])//t->v[c - 'a'] == nullptr
t->v[c-'a'] = new Tree();//一開始都是空的都要分配空間
t = t->v[c-'a'];
}
t->word_here = true;
}
static bool search(Tree* t, const string &s){
for(char c:s){
if(!t->v[c-'a']->word_here)//查找c失敗 false 這裏判斷之前的前綴是不是單獨的一個字符串
return false;
t = t->v[c-'a'];
}
return true;
}
};
string longestWord(vector<string>& words) {
Tree* root = new Tree();
for(string &s:words)
Tree::insert(root, s);//插入
string longest;
for(string &s:words)
if(Tree::search(root, s)){
if(s.size()>longest.size())
longest=s;
else if(s.size()==longest.size()&&s<longest)////這裏最後比較大小
longest=s;
}
return longest;
}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////參考/////////////////////////////////////////////////////////
#include<cstdio>
#include<cstdlib>
using namespace std;
char s[11];
struct Trie{
Trie* next[26]; //結構體指針 有26種字符
int sum; //單詞出現的次數
Trie(){ //構造函數 便於初始化
for(int i=0;i<26;i++){ //初始化
next[i]=NULL; //初始時,每個字符所對應數組下標中的指針爲空
}
sum=0;
}
}root;
void insert(char* s) //創建字典樹 在字典樹上插入結點
{
Trie* p=&root; //從根結點開始遍歷
for(int i=0;s[i];i++){ //遍歷單詞的每一個字符
if(p->next[s[i]-'a']==NULL){ //判斷字符所對應結構體指針數組下標中的指針是否爲空
p->next[s[i]-'a']=new Trie; //如果爲空 就新建一個結點
}
p=p->next[s[i]-'a']; //將指針指向當前字符所對應的結構體指針數組的下標所對應的地址
p->sum++;
}
}
int find(char* s) //查找單詞
{
Trie* p=&root; //從根結點開始遍歷
for(int i=0;s[i];i++){ //遍歷單詞的每一個字符
if(p->next[s[i]-'a']==NULL)return 0; // 如果下標所對應的指針爲空 查找失敗
else p=p->next[s[i]-'a']; //如果不爲空 遍歷下一個字符 直至遍歷結束
}
return p->sum; //返回遍歷完的最後一個結點中所對應的數據 代表當前當前單詞出現的次數
}
int main(){
while(gets(s)&&s[0]!='\0') //讀取字典中的單詞 將其插入字典樹中
insert(s);
while(scanf("%s",s)==1){ //在字典樹中查找單詞出現的次數
printf("%d\n",find(s));
}
return 0;
}