HDU - 1251 统计难题(Trie字典树,map容器的应用)

题目链接https://vjudge.net/contest/341616#problem/B
在这里插入图片描述
分析
对于该开始输入的一个字符串集合,我们需要考虑每一个字符串它的前缀
例如第一个字符串banana,它的前缀可以表示为b ba ban bana banan banana
关键是如何利用字典树把这些前缀信息表示出来
我们知道在Trie树中,额外信息保存在结点中,利用好book数组是关键。
对于每一个字符串的每一个字符,若该字符在字典树中没有出现过,就需要重新开辟结点来储存它,所以我们可以标记结点,看每一个结点出现过几次。
代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int ch[N][30],tot=1,book[N];
void inser(char *s)
{
    int u=1,c;
    for(int i=0; s[i]!='\0'; i++)
    {
        int c=s[i]-'a';
        if(!ch[u][c])
            ch[u][c]=++tot;
        u=ch[u][c];
        book[u]++;
    }
}
int compar(char *s)
{
    int u=1,c;
    for(int i=0; s[i]!='\0'; i++)
    {
        c=s[i]-'a';
        if(!ch[u][c])
            return -1;
        u=ch[u][c];
    }
    return book[u];
}
int main()
{
    memset(book,0,sizeof(book));
    char a[20];
    while(gets(a))
    {
        if(a[0]=='\0')
            break;
        inser(a);
    }
    char t[20];
    while(~scanf("%s",t))
    {
        int d=compar(t);
        if(d==-1)
            printf("0\n");
        else
            printf("%d\n",d);
    }
    return 0;
}

对于该字符串集合,也可以用map容器把每一个前缀表示出来
代码

#include<cstdio>
#include<cstring>
#include<string.h>
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
map<string,int>mp;
char a[30],b[30];
int main()
{
    while(gets(a))
    {
        if(a[0]=='\0')
            break;
        int r=0;
        for(int i=0; a[i]!='\0'; i++)
        {
            b[r++]=a[i];/*找出所有的前缀进行标记*/
            b[r]='\0';
            mp[b]++;
            //printf("b-->%s\n",b);
        }
    }
    while(~scanf("%s",a))
        printf("%d\n",mp[a]);
    return 0;
}

在这里插入图片描述
喜欢一个人,始于颜值,陷于才华,忠于人品。

发布了165 篇原创文章 · 获赞 6 · 访问量 5084

猜你喜欢

转载自blog.csdn.net/lylzsx20172018/article/details/103016691
今日推荐