題意跟簡單,就是模擬輸入法,統計前綴的頻率時要把相同前綴的單詞頻率相加,所以只能採用離線算法,預先把詞頻統計出來,這個用字典樹統計,同樣輸入數字按鍵時也要在字典樹上查找,爲此建了兩顆字典樹,一顆統計詞頻,一顆查詢數字鍵。
#include<vector> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 111; const int MAXM = 1010; typedef struct charNode{ string str; int cnt; charNode(){ cnt = 0; str = ""; } charNode(string str, int cnt){ this->cnt = cnt; this->str = str; } bool operator < (const charNode &A) const{ return cnt > A.cnt; } }charNode; typedef struct Node{ int issort; vector<charNode>target; Node *child[8]; Node(){ issort = 0; target.clear(); for(int i = 0; i < 8; i ++) child[i] = NULL; } }Node; typedef struct Word{ int cnt; Word *child[26]; Word(){ cnt = 0; for(int i = 0; i < 26; i ++) child[i] = NULL; } }Word; Node *rt; Word *charrt; inline int hash(char c){ if(c >= 'a' && c <= 'c') return 0; if(c >= 'd' && c <= 'f') return 1; if(c >= 'g' && c <= 'i') return 2; if(c >= 'j' && c <= 'l') return 3; if(c >= 'm' && c <= 'o') return 4; if(c >= 'p' && c <= 's') return 5; if(c >= 't' && c <= 'v') return 6; if(c >= 'w' && c <= 'z') return 7; } inline void buildTrieChar(char str[], int cnt){ Word *tmp = charrt; while(str[0]){ int idx = str[0]-'a'; if(tmp->child[idx] == NULL) tmp->child[idx] = new Word(); tmp = tmp->child[idx]; tmp->cnt += cnt; str++; } } inline int cntTime(char *low, char *high){ Word *tmp = charrt; for(char *i = low; i <= high; i ++){ int idx = *i - 'a'; tmp = tmp->child[idx]; } return tmp->cnt; } inline void buildTrieNum(char str[]){ Node *tmp = rt; int len = strlen(str); for(int i = 0; i < len; i ++){ int idx = hash(str[i]); if(tmp->child[idx] == NULL) tmp->child[idx] = new Node(); Node *p =tmp->child[idx]; int cnt = cntTime(str, str+i); p->target.push_back(charNode(string(str, 0, i+1), cnt)); tmp = p; } } inline void input(char str[]){ int i; Node *tmp = rt; int len = strlen(str); for(i = 0; i < len-1; i ++){ int idx = str[i] - '2'; if(tmp->child[idx]){ tmp = tmp->child[idx]; if(!tmp->issort){ sort(tmp->target.begin(), tmp->target.end()); tmp->issort = 1; } int cnt = tmp->target.at(0).cnt; cout << tmp->target.at(0).str << endl; }else break; } for(int j = i; j < len - 1; j ++) printf("MANUALLY "); } int main(){ char str[MAXM][MAXN]; int t, n, m, cnt; #ifndef ONLINE_JUDGE freopen("in.cpp", "r", stdin); #endif scanf("%d", &t); for(int i = 1; i <= t; i ++){ rt = new Node(); charrt = new Word(); printf("Scenario #%d: ", i); scanf("%d", &n); for(int i = 0; i < n; i ++){ scanf("%s%d", str[i], &cnt); buildTrieChar(str[i], cnt); } for(int i = 0; i < n; i ++) buildTrieNum(str[i]); scanf("%d", &m); for(int i = 0; i < m; i ++){ scanf("%s",str[i]); input(str[i]); printf(" "); } printf(" "); } return 0; }