HDU 1251 统计难题(字典树)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1251

字典树就是这样一幅图

 

即每个结点有多个儿子结点。。。然后单词的前缀会在树中重合,
而结点的数据域随题目而变,例如这题,数据域prefixNum表示含以该结点结尾的前缀的单词的个数。
那么如果你想知道树中某单词是否存在,则数据域isWord == 1表示存在以该结点结尾的单词
 
字典树效率高在于他只需要遍历该单词
 
 
#include <iostream>
using namespace std;

struct Node
{
    struct Node *child[26];
    int perfixNum;//表示含以该结点结尾的前缀的单词的个数
};

Node *root;

void Init()//初始化
{
    root = new Node;
    for (int i = 0; i < 26; i++)
    {
        root->child[i] = NULL;
    }
}

//插入
void Insert(char word[])
{
    int len = strlen(word);
    Node *pNode = root;
    for (int i = 0; i < len; i++)
    {
        if (pNode->child[word[i] - 'a'] == NULL)
        {
            //不存在该结点,则创建一个
            Node *newNode = new Node;
            newNode->perfixNum = 1;
            for (int j = 0; j < 26; j++)
            {
                newNode->child[j] = NULL;
            }

            pNode->child[word[i] - 'a'] = newNode;
        }
        else
        {
            pNode->child[word[i] - 'a']->perfixNum++;
        }
        
        pNode = pNode->child[word[i] - 'a'];
    }
}

//查找,通过遍历该单词到该单词的结尾结点的prefixNum就是答案了
int Find(char word[])
{
    int len = strlen(word);
    Node *pNode = root;
    int i;
    for (i = 0; i < len; i++)
    {
        if (pNode->child[word[i] - 'a'] != NULL)
        {
            pNode = pNode->child[word[i] - 'a'];
        }
        else
        {
            break;
        }
    }

    if (i == len)
    {
        return pNode->perfixNum;
    }
    else
    {
        return 0;
    }
}

int main()
{

    char word[15], prefixWord[15];
    Init();
    while (gets(word), word[0] != 0)
    {
        Insert(word);
    }

    while (gets(prefixWord) != NULL)
    {
        printf("%d\n", Find(prefixWord));
    }
    return 0;
}

 

posted on 2012-10-20 17:34  [S*I]SImMon_WCG______*  阅读(274)  评论(0编辑  收藏  举报

导航