字典树(Trie树)模板 数组表示 + 链表表示

 数组模拟,缺点是并不知道要开多大,可能会出现数组开小导致wrong answer。

对应题目:hdu 1251 

#include <iostream>
#include <cstdio>
#include <cstring>
#define fuck cout << "wtf???\n"
using namespace std;

typedef long long ll;
const int maxn = 1e6 + 100;

int num;
struct Tries
{
    int child[27];
    int cnt;
    void Init(){
        cnt = 0;
        memset(child, -1, sizeof(child));
    }
}Trie[maxn];

void Insert(string st)
{
    int tmp = 0;
    for(int i = 0; i < (int)st.size(); ++ i)
    {
        int r = st[i] - 'a';
        if(Trie[tmp].child[r] == -1)
        {
            Trie[tmp].child[r] = ++num;
            Trie[num].Init();
        }
        tmp = Trie[tmp].child[r];
        Trie[tmp].cnt++;
    }
}

int Query(string st)
{
    int tmp = 0;
    for(int i = 0; i < (int)st.size(); ++ i)
    {
        int r = st[i] - 'a';
        if(Trie[tmp].child[r] == -1)
        {
            return 0;
        }
        tmp = Trie[tmp].child[r];
    }
    return Trie[tmp].cnt;
}

void init()
{
    num = 0;
    Trie[0].cnt = 0;
    memset(Trie[0].child, -1, sizeof(Trie[0].child));
}

string st;

bool read()
{
    char ch;
    st.clear();
    int cnt = 0;
    while(ch = getchar())
    {
        if(ch == '\n')
            break;
        //cout << ch << endl;
        cnt++;
        st += ch;
    }
    if(cnt == 0)	return false;
    else	return true;
}

int main()
{
    //freopen("in.txt", "r", stdin);
    init();
    while(read())
    {
        Insert(st);
    }
    while(cin >> st)
    {
        cout << Query(st) << endl;
    }
    return 0;
}

链表表示:不用担心空间的问题了,但是反复申请空间还是比较费时间的,而且访问速度肯定是比不上数组。

对应题目:hdu 1075

#include <iostream>
#include <cstdio>
#include <cstring>
#define fuck cout << "wtf???\n"
using namespace std;

char st[3030], str[3030];

struct node
{
    node *child[26];
    char ss[15];
    bool flag;
    void Init(){
        for(int i = 0; i < 26; ++ i)
            child[i] = NULL;
        flag = false;
    }
}*Trie;

void Insert(char *st, char *str)
{
    int len = strlen(st);
    node *tmp = Trie;
    for(int i = 0; i < len; ++ i)
    {
        int r = st[i] - 'a';
        if(tmp->child[r] == NULL)
        {
            tmp->child[r] = new node;
            tmp->child[r]->Init();
        }
        tmp = tmp->child[r];

    }
    strcpy(tmp->ss, str);
    tmp->flag = true;
}

void Search(int l, int r)
{
    node *tmp = Trie;
    for(int i = l; i < r; ++ i)
    {
        int x = str[i] - 'a';
        if(tmp->child[x] == NULL)
        {
            for(int j = l; j < r; ++ j)
                printf("%c", str[j]);
            return ;
        }
        tmp = tmp->child[x];
    }
    if(tmp->flag)
        printf("%s", tmp->ss);
    else
    {
        for(int j = l; j < r; ++ j)
            printf("%c", str[j]);
    }
}

bool read()        //害怕超时就自己写了个读入函数
{
    char ch;
    int i = 0;
    while(ch = getchar())
    {
        if(ch == '\n')
            break;
        str[i++] = ch;
    }
    str[i] = '\0';
    if(strcmp(str, "END") == 0)
        return false;
    return true;
}

int main()
{
    //freopen("in.txt", "r", stdin);
    Trie = new node;
    Trie->Init();
    scanf("%s", st);
    while(scanf("%s", st))
    {
        if(strcmp(st, "END") == 0)
            break;
        scanf("%s", str);
        Insert(str, st);
    }
     scanf("%s", st);
     getchar();
     while(1)
     {
     	if(!read())
     		break;
     	 int pos = 0;
     	 int i = 0;
     	 int len = strlen(str);
     	 while(i < len)
     	 {
     	 	while((str[i] < 'a' || str[i] > 'z') && i < len)
     	 	{
     	 		printf("%c", str[i]);
     	 		i++;
     	 	}
     	 	pos = i;
     	 	while((str[i] >= 'a' && str[i] <= 'z') && i < len)
     	 		++ i;
            if(pos >= len || i > len)
                continue;
     	 	Search(pos, i);
     	 }
     	printf("\n");
     }
    return 0;
}

 

    原文作者:Trie树
    原文地址: https://blog.csdn.net/aqa2037299560/article/details/84330318
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞