POJ 1451 T9

題意跟簡單,就是模擬輸入法,統計前綴的頻率時要把相同前綴的單詞頻率相加,所以只能採用離線算法,預先把詞頻統計出來,這個用字典樹統計,同樣輸入數字按鍵時也要在字典樹上查找,爲此建了兩顆字典樹,一顆統計詞頻,一顆查詢數字鍵。

#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; 
}



原文地址:https://www.cnblogs.com/anhuizhiye/p/3933142.html