POJ1451 T9【Trie】

版权声明:本文为博主原创文章,转载请务必注明出处。 https://blog.csdn.net/wlx65003/article/details/51819723

题目链接

http://poj.org/problem?id=1451

思路

让你模拟手机输入法。
我这里是同步造了两棵字典树,一棵以字母为节点,统计probability,另一棵以键盘数字为节点,存当前按键路径probability最大的词和它的probability。
同步的方法是,用一个映射,将一个单词映射成数字,从而在两棵树之间同步插入。

看了下网上的代码,好像不用第一棵树也能算出probability,直接几个for搞定,代码短很多,哪天试试。

AC代码

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;


struct word //trie of word
{
    word()
    {
        for (int i = 0; i < 26; ++i)
            next[i] = NULL;
        p = 0;
    }
    ~word()
    {
        for (int i = 0; i < 26; ++i)
        {
            if (next[i] != NULL)delete next[i];
        }
    }
    int p;
    word *next[26];
};
struct num //trie of number
{
    num()
    {
        for (int i = 0; i < 10; ++i)
            next[i] = NULL;
        p = 0;
    }
    ~num()
    {
        for (int i = 0; i < 10; ++i)
        {
            if (next[i] != NULL)delete next[i];
        }
    }
    string s;
    int p;
    num *next[10];
};

int mp[] = { 2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9 };
void insert_word(string s, int p, word* root_word, num* root_num)//insert word to both tries
{
    word *now_word = root_word;
    num *now_num = root_num;
    for (int i = 0; i < s.length(); ++i)
    {
        if (now_word->next[s[i] - 'a'] == NULL)
        {
            now_word->next[s[i] - 'a'] = new word;
        }
        now_word = now_word->next[s[i] - 'a'];
        now_word->p += p;

        if (now_num->next[mp[s[i] - 'a']] == NULL)
        {
            now_num->next[mp[s[i] - 'a']] = new num;
        }
        now_num = now_num->next[mp[s[i] - 'a']];

        string temp_s = s.substr(0, i + 1);
        if (now_word->p > now_num->p ||
            (now_word->p == now_num->p && temp_s < now_num->s))
        {
            now_num->p = now_word->p;
            now_num->s = temp_s;
        }
    }
}

void find_num(string s, num* root_num)//search in num trie and print answer
{
    num *now = root_num;
    for (int i = 0; i < s.length() - 1; ++i)//ignore the end '1'
    {
        if (now->next[s[i] - '0'] == NULL)
        {
            for(int j=0 ; j<s.length()-1-i ; ++j)
            {
                printf("MANUALLY\n");
            }
            break;
        }
        now = now->next[s[i] - '0'];
        cout << now->s << "\n";
    }
}
int main()
{
    int T;
    scanf("%d", &T);
    for (int k = 1; k <= T; ++k)
    {
        word *root_word = new word;
        num *root_num = new num;
        int w;
        scanf("%d", &w);
        while (w--)
        {
            string s;
            int p;
            cin >> s >> p;
            insert_word(s, p, root_word, root_num);
        }
        int m;
        scanf("%d", &m);
        printf("Scenario #%d:\n", k);
        while (m--)
        {
            string s;
            cin >> s;
            find_num(s, root_num);
            printf("\n");
        }
        printf("\n");
        delete root_word;
        delete root_num;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wlx65003/article/details/51819723
t9