字典树(Trie)

字典树,顾名思义,就是一种对字母等字符串进行处理的一种特殊数据结构。说白了,就是二十六叉树。定义一个头指针,每次从头指针开始操作。

有两种常用的操作:

1.查询某个字符串的出现次数。

每个节点的count置为0,直到这个字符串结束,在末尾处count++.这样,就记录了该字符串的出现次数。

2.查询某个字符串特定序列出现的次数。

每个节点的count初始化为0,当读入一个字符,则count++。这样,查询时,这个节点count记录的就是从头结点到该结点特定序列出现的次数。可以用于统计单词的前缀一类的题目。

例题:

给你一堆英文单词(可能有4000000个。用普通查询铁定让你TLE)。找出出现次数最多的,输出这个单词,并输出出现的次数。

思路:

如果数据范围很小,我们可以用STL里面的map映射来做,但是数据范围太大,用普通的数据结构肯定会超时,所以要考虑更优的数据结构。当然,这题也是赤裸裸的字典树应用。当然,也可以用hash来做。懒的写了,参考学长代码

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=2*1e5+10;
int n,m,q,k,ans,sum,top;
char ch1[N],ch2[N];
struct Dictree///字典树
{
    int count;///单词出现次数
    struct Dictree  *tree[26];///26个子节点
}*a;
void init()
{
    a=new Dictree;
    for(int i=0; i<26; ++i)  ///子节点置空
    {
        a->tree[i]=NULL;
    }
}
int insert(char str[])
{
    int len,j;
    Dictree *head=a;///head是头指针
    len=strlen(str);
    for(int i=0; i<len; ++i)
    {
        j=(int)(str[i]-'a');
        if(head->tree[j]==NULL)
        {
            head->tree[j]=new Dictree;
            head=head->tree[j];
            head->count=0;
            for(int k=0; k<26; k++)
            {
                head->tree[k]=NULL;
            }
        }
        else head=head->tree[j];
    }
    head->count++;
    return head->count;
}
int main()
{
    int num,maxx=0;
    init();
    scanf("%d",&num);
    for(int i=0; i<num; ++i)
    {
        scanf("%s",ch1);
        int ans=insert(ch1);
        if(ans>maxx)
        {
            maxx=ans;
            strcpy(ch2,ch1);
        }
    }
    printf("%s %d\n", ch2,maxx);
}

数据范围较小,可用map映射 

#include <bits/stdc++.h>
using namespace std;
const int N=2*1e5+10;
int n,m,q,k,ans,sum,top;
char ch1[N],ch2[N];
map<string,int>dictree;
int main()
{
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%s",ch1);
        dictree[ch1]++;///每个单词出现次数
    }
    map<string,int >::iterator ita,itb;
    for(ita=dictree.begin(),itb=dictree.begin(); ita!=dictree.end(); ++ita)
    {
        if(ita->second>itb->second)
        {
            itb=ita;
        }
    }
    cout<<itb->first<<" "<<itb->second<<endl;
    return 0;
}



你可能感兴趣的:(数据结构,字典树)