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;

}

 

你可能感兴趣的:(HDU)