專做奢侈品的網站廣州seo優(yōu)化電話
1、定義
高效的存儲和查找字符串集合的數(shù)據(jù)結構
它的優(yōu)點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高
2、構建
我們可以使用數(shù)組來模擬實現(xiàn)Trie樹。
我們設計一個二維數(shù)組 son[N] [26] 來模擬整個樹的結構,而cnt[N] 來記錄單詞個數(shù)。
舉個例子: son[1][1]=2 代表的是 1號節(jié)點 的一個值為b的節(jié)點 是 2號節(jié)點。而son[1][0]=0 則表示1號節(jié)點不存在 值為 a 的節(jié)點。
3、代碼分析
1、定義
son[N][26]
下標是x的點
x這個節(jié)點的所有的兒子是去存儲到son[x][26]里面
son[x][0]就是第一個節(jié)點 son[x][1]就是第二個節(jié)點
cont[x]表示以x為結尾的單詞有多少個
int son[N][26], cnt[N], idx;
// 0號點既是根節(jié)點,又是空節(jié)點
// son[][]存儲樹中每個節(jié)點的子節(jié)點
// cnt[]存儲以每個節(jié)點結尾的單詞數(shù)量
2、插入操作
// 插入一個字符串
void insert(char *str)
{int p = 0;//從根節(jié)點開始,從前往后遍歷for (int i = 0; str[i]; i ++ ){//將a-z 映射成 0 - 25int u = str[i] - 'a';//如果當前節(jié)點不存在 => p節(jié)點不存在u這個兒子//就創(chuàng)建出來if (!son[p][u]) son[p][u] = ++ idx;//將該值賦給pp = son[p][u];}//以該點為結尾的數(shù)字多了一個cnt[p] ++ ;
}
3、查詢操作
// 查詢字符串出現(xiàn)的次數(shù)
int query(char *str)
{//從根節(jié)點開始int p = 0;for (int i = 0; str[i]; i ++ ){int u = str[i] - 'a';//如果當前節(jié)點不存在子節(jié)點的話if (!son[p][u]) return 0;p = son[p][u];}//返回以p結尾的單詞的數(shù)量return cnt[p];
}
3.題目
維護一個字符串集合,支持兩種操作:
1、 I x向集合中插入一個字符串 x;
2、 Q x詢問一個字符串在集合中出現(xiàn)了多少次。
共有 N個操作,所有輸入的字符串總長度不超過10^5 ,字符串僅包含小寫英文字母。
輸入格式
第一行包含整數(shù) N,表示操作數(shù)。
接下來 N行,每行包含一個操作指令,指令為 I x 或 Q x 中的一種。
輸出格式
對于每個詢問指令 Q x,都要輸出一個整數(shù)作為結果,表示 x在集合中出現(xiàn)的次數(shù)。
每個結果占一行。
數(shù)據(jù)范圍
1≤N≤2?10^4
輸入樣例:
5
I abc
Q abc
Q ab
I ab
Q ab
輸出樣例:
1
0
1
#include <iostream>using namespace std;const int N = 100010;int son[N][26],idx,cnt[N];
char str[N];//向集合中插入一個字符串 x
void insert(char str[])
{int p = 0;for (int i = 0; str[i]; i++){int u = str[i] - 'a';//將這個字符從a-z變成 0-25if (!son[p][u]) son[p][u] = ++idx;p = son[p][u];}cnt[p]++;
}//詢問一個字符串在集合中出現(xiàn)了多少次
int query(char str[])
{int p = 0;for (int i = 0; str[i]; i++){int u = str[i] - 'a';if (!son[p][u]) return 0;p = son[p][u];}return cnt[p];
}int main()
{int n;cin >> n;while (n--){char op[2];cin >> op >> str;if (op[0] == 'I') insert(str);else cout << query(str)<< endl;}return 0;
}