HDOJ 1298 T9(trie树简单应用)

意:

一串数字,给出出现频率最高的那个单词。

思路:

字典树:首先是建树,其实最麻烦的是概率处理部分,因为题目给定的单词都是按照字典有序排列的,所以可以对于概率进行一遍预处理,然后建树的时候就可以直接更新判断了。

题目同 POJ 1451 http://poj.org/problem?id=1451

#include <iostream>
#include <vector>
using namespace std;

struct node {
    bool isword;
    int prob, index;
    int child[10];
    node(bool _isword, int _prob, int _index) 
        :   isword(_isword), prob(_prob), index(_index)
    { memset(child, 0, sizeof(child)); }
};

vector<node> trie;

int tab[256];
char dict[1010][102];
int prob[1010][102];

void Insert(const char* word, int i, int index, int rt)
{
    if (word[i] == '\0')
    {
        trie[rt].isword = true;
        return ;
    }

    int m = tab[word[i]];
    if (trie[rt].child[m])
    {
        if (trie[trie[rt].child[m]].prob < prob[index][i])
        {
            trie[trie[rt].child[m]].prob = prob[index][i];
            trie[trie[rt].child[m]].index = index;
        }
        else if (trie[trie[rt].child[m]].prob == prob[index][i])
        {
            if (strncmp(dict[index], dict[trie[trie[rt].child[m]].index], i + 1) < 0)
                trie[trie[rt].child[m]].index = index;
        }

        Insert(word, i + 1, index, trie[rt].child[m]);
    }
    else
    {
        trie.push_back(node(false, 0, 0));
        trie[rt].child[m] = trie.size() - 1;
        trie[trie[rt].child[m]].index = index;
        trie[trie[rt].child[m]].prob = prob[index][i];
        Insert(word, i + 1, index, trie[rt].child[m]);
    }
}

int Query(const char* word, int rt)
{
    if (*word == '\0')
        return trie[rt].index;

    int m = *word - '0';
    if (!trie[rt].child[m])
        return -1;
    else
        return Query(word + 1, trie[rt].child[m]);
}

void Init()
{
    tab['a'] = tab['b'] = tab['c'] = 2;
    tab['d'] = tab['e'] = tab['f'] = 3;
    tab['g'] = tab['h'] = tab['i'] = 4;
    tab['j'] = tab['k'] = tab['l'] = 5;
    tab['m'] = tab['n'] = tab['o'] = 6;
    tab['p'] = tab['q'] = tab['r'] = tab['s'] = 7;
    tab['t'] = tab['u'] = tab['v'] = 8;
    tab['w'] = tab['x'] = tab['y'] = tab['z'] = 9;
}

int main()
{
    int cases;
    Init();
    scanf("%d", &cases);
    for (int c = 1; c <= cases; ++c)
    {
        int n, p;
        scanf("%d", &n);
        printf("Scenario #%d:\n", c);

        trie.clear();
        trie.push_back(node(false, 0, 0));

        memset(prob, 0, sizeof(prob));
        for (int i = 1; i <= n; ++i)
        {
            scanf("%s %d", dict[i], &p);
            int len = strlen(dict[i-1]);
            for (int j = 0; dict[i][j] != '\0'; ++j)
            {
                prob[i][j] = p;
                if (j < len && !strncmp(dict[i], dict[i-1], j + 1))
                    prob[i][j] += prob[i-1][j];
            }
            Insert(dict[i], 0, i, 0);
        }

        char word[110], is[110], os[110];
        scanf("%d", &n);
        while (n--)
        {
            scanf("%s", is);
            for (int i = 0; is[i] != '1'; ++i)
            {
                word[i] = is[i];
                word[i+1] = '\0';
                int id = Query(word, 0);
                if (id != -1)
                {
                    int j = 0;
                    for (j = 0; j <= i; ++j)
                        os[j] = dict[id][j];
                    os[j] = '\0';
                    printf("%s\n", os);
                }
                else 
                    printf("MANUALLY\n");
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kedebug/p/2875545.html