hdu1251 字典树典型

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

题意为:先给定一个单词列表,然后输入字符串,统计以该字符串为前缀的单词数量。

第一次接触字典树,这个题目就是要用字典树的插入、查询来做。

有几个地方要注意一下:

  1. 插入时候,不是字母结束时将p->cnt++,而是遇到字母:

    没出现过:初始化1,表明此次出现

    出现过:cnt++

    这样,p->cnt记录的就是从根结点到head结点的前缀出现的次数

  2. 怎样判断空行:用strlen()计算字符串的长度,如果长度为0,说明为空行,退出输入循环。

  3. 关于内存的释放,虽然程序结束后会自动释放,但还是养成一个手动释放的好习惯吧。

贴上代码:

扫描二维码关注公众号,回复: 2464918 查看本文章
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

struct Node
{
    int cnt;
    struct Node *child[26];

    Node(){
        cnt = 0;
        for (int i = 0; i < 26; i++)
            child[i] = NULL;
    }
}*root;


//插入算法
void Insert(char s[])
{
    Node *p = root;

    int len = strlen(s);
    for(int i = 0; i < len; i++) {

        //求出当前字母的下标;
        int index = (int)(s[i] - 'a');
        //如果字母不存在,则插入
        if (p->child[index] == NULL)
        {
            p->child[index] = new Node();
            p = p->child[index];
            p->cnt = 1;   //将当前字母置位1,表示出现过一次
        }
        //当前字母存在,则继续寻找可插入的位置
        else
        {
            p = p->child[index];
            p->cnt++;     //cnt代表的是已经经过的单词前缀数量
        }
    }
}

//查询算法
int Find(char s[])
{
    int len = strlen(s);
    Node *p = root;
    for (int i = 0; i < len; i++)
    {
        int index = (int)(s[i] - 'a');
        if (p->child[index] == NULL)
            return 0;
        else p = p->child[index];
    }
    return p->cnt;
}
//释放所申请的空间
void release(Node *root)
{
    if (root == NULL)
        return;
    for (int i = 0; i < 26; i++)
    {
        if ( root->child[i] != NULL )
            release( root->child[i] );
    }
    delete root;
    root = NULL;
}

int main()
{
    root = new Node();
    char word[10], que[10];
    while(gets(word) && strcmp(word, "") != 0)
    {
        Insert(word);
    }
    while (gets(que) && strcmp(que, "") != 0)
    {
        int num = Find(que);
        cout << num << endl;
    }
    release(root);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39548163/article/details/81191832