1. 程式人生 > >字典樹(Trie樹)模板 陣列表示 + 連結串列表示

字典樹(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;
}