題目描述:
給定n個字串s1,s2…sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s1~sn中有多少個字串是t的字首。
輸入字串的總長度不超過106,僅包含小寫字母。
輸入格式
第一行輸入兩個整數n,m。接下來n行每行輸入乙個字串si。接下來m行每行乙個字串t用以詢問。
輸出格式
對於每個詢問,輸出乙個整數表示答案。每個答案佔一行。
輸入樣例:
3 2
abbc
abcabc
efg
輸出樣例:
2
0
分析:
本題考查字典樹(trie)。
首先簡單拷貝下字典樹的定義:trie,又稱字典樹、單詞查詢樹或鍵樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字串(但不僅限於字串),所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是:利用字串的公共字首來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比雜湊樹高。
再拷貝下字典樹的性質:
1.根節點不包含字元,除根節點外每乙個節點都只包含乙個字元。
2.從根節點到某一節點,路徑上經過的字元連線起來,為該節點對應的字串。
3.每個節點的所有子節點包含的字元都不相同。
只看文字說明可能比較抽象,下面開始構建一棵字典樹。開始初始化乙個根結點,然後插入see,123層一次插入了see,然後插入pain,第一層沒有p於是新建乙個p結點,再依次插入ain;緊接著插入pand,發現12層有現成的pa於是在34層繼續插入nd;最後插入dog,生成的字典樹如下。由26個小寫字母構成單詞組成的字典樹每個結點最多有26個孩子
字典樹的形狀並不難理解,問題是如何用**去實現它。
首先,分析下字典樹的插入:
void insert()
cnt[p]++;
}
這裡有個二維陣列son,第一維p表示結點的編號,第二維s表示當前結點是什麼字母,將a - z對映到0 - 25.son[p][s]的值表示其孩子結點的編號。這裡格外要注意的是,除了第一次插入的字元外(比如插入abc,第一次插入的是a),字典樹其它層次的結點son陣列的第一維均表示其編號,為啥第一次插入的字元不用編號而是用0作為p值呢?是為了充當索引的作用,在查詢時能夠很快地找到。以本題樣例來進行說明:首先str = 「ab」,插入的第乙個節點為a,值為a - a = 0,首先判斷下son[0][0]是否存在,不存在則插入,同時宣告如果緊接著插入它的孩子結點,編號應該是1,於是繼續插入b,編號為1,值為1,son[1][1] = 2表示如果接下來有孩子結點,編號應該是2;接著插入bc,發現son[0][1]不存在,於是插入,其孩子結點編號為3也就是c結點;最後插入abc,發現son[0][0]和son[1][1]均存在,於是緊接著son[1][1]後面插入字元c。這裡的cnt陣列是給每次插入的字串的最後乙個字元做上乙個結束標記,方便查詢時統計有多少單詞數。(個人淺見,未參考其它文件,如有偏差,敬請指出)。
接著,分析下字典樹的查詢:
int search()
return res;
}
比如查詢abc,從第乙個字元開始,發現son[0][0]存在,於是判斷下是不是有以當前遍歷到的字元為結尾的單詞,如果有,說明就是abc的字首了,加上單詞數;接著查詢son[1][1],發現依然存在,而且有ab字串,以b為結尾的字元有cnt陣列的標記,於是加上單詞數1;接著發現c在字典樹里也有,於是又加上了單詞數,此次查詢找到了abc的字首ab和abc。第二次查詢efg,因為son[0][4] = 0.不存在索引結點為e,所以查詢終止。
本題總的**如下:
#include using namespace std;
const int maxn = 500000,maxm = 1000005;
int n,m;
int son[maxn][26],cnt[maxn],idx;
char str[maxm];
void insert()
cnt[p]++;
}int search()
return res;
}int main()
while(m--)
return 0;
}
Acwing 142 字首統計
給定n個字串s1,s2 sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s1 sn 中有多少個字串是t的字首。輸入字串的總長度不超過106 僅包含小寫字母。輸入格式 第一行輸入兩個整數n,m。接下來n行每行輸入乙個字串si 接下來m行每行乙個字串t用以詢問。輸出格式 對於每個詢問,輸出乙個整數表...
acwing 142 字首統計 字典樹
給定n個字串s1,s2 sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s1 sn中有多少個字串是t的字首。輸入字串的總長度不超過106,僅包含小寫字母。輸入格式 第一行輸入兩個整數n,m。接下來n行每行輸入乙個字串si。接下來m行每行乙個字串t用以詢問。輸出格式 對於每個詢問,輸出乙個整數表示...
AcWing 142 字首統計(字典樹)
給定n個字串s1,s2 s n s1,s2 sn s1,s2 sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s 1 s1 s1 s n sn sn中有多少個字串是t的字首。輸入字串的總長度不超過10 6 106 106,僅包含小寫字母。輸入格式 第一行輸入兩個整數n,m。接下來n行每行輸入乙個...