標籤:首碼樹 string uva set
給定一個詞典,要求求出其中所有的複合詞,即恰好有兩個單詞串連而成的詞
trie儲存以該單詞為首碼的單詞數量,然後對於每個單詞,看在字典中的以該單詞為首碼的單詞“減去”原單詞剩下的單詞是否在字典中,如果是儲存這個答案到ans的set中
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string>#include<map> #include<set>#define eps 1e-6 #define LL long long using namespace std; const int maxn = 120000 + 100;const int INF = 0x3f3f3f3f;struct Trie {int ch[maxn][30];int val[maxn];int sz;Trie() {sz = 1; memset(ch[0], 0, sizeof(ch[0]));}int idx(char c) { return c - 'a';}void insert(char *s) {int u = 0, n = strlen(s);for(int i = 0; i < n; i++) {int c = idx(s[i]);if(!ch[u][c]) {memset(ch[sz], 0, sizeof(ch[sz]));val[sz] = 0;ch[u][c] = sz++;}else val[ch[u][c]]++;u = ch[u][c];}}int find(char *s) {int u = 0, n = strlen(s);for(int i = 0; i < n; i++) {int c = idx(s[i]);if(!ch[u][c]) return 0;u = ch[u][c];}return val[u];}} trie;vector<string> dic;set<string> word;set<string> ans;void init() {string tmp;while(cin >> tmp) {dic.push_back(tmp);word.insert(tmp);trie.insert((char *)tmp.c_str());}}void solve() {int sz = dic.size();for(int i = 0; i < sz; i++) {//cout << (char *)dic[i].c_str() << endl;int cnt = trie.find((char *)dic[i].c_str());// cout << cnt << endl;int wsz = dic[i].size();for(int j = 1; j <= cnt; j++) {if(word.count(dic[i+j].substr(wsz, dic[i+j].size()-wsz)))ans.insert(dic[i+j]);}}for(set<string>::iterator it = ans.begin(); it != ans.end(); it++) cout << *it << endl;}int main() {//freopen("input.txt", "r", stdin);init();solve();return 0;}
uva 10391複合詞compound words(Trie+set)