每次都好痛苦哦···因为以前没有学扎实····今天呢,我们来复习字典树,字典树有两种方法,一种是静态的方法用二维数组搞···另一种是用链表的方法。学习这个东西就是应该举一反三,触类旁通,所以呢,我们先来学习LRJ大白书上的静态存储法,首先贴下我的模板喽
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<cmath>
#define ll __int64
#define MAX 500009
using namespace std;
const int sigma_size = 26;
const int maxnode = 500000;
struct Tire
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;//节点总数
Tire()
{
sz = 1;//初始时只有一个根结点
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
}
int idx(char c)
{
return c - 'a';//字符C的编号
}
//插入字符,附加信息为V,注意V必须为非0,因为0代表本节点不是单词节点
void Insert(char* s)
{
int u = 0,n = strlen(s);
for(int i = 0; i<n; i++)
{
int c = idx(s[i]);
if(!ch[u][c])//结点不存在
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz] = 0; //中间结点附加为0
ch[u][c] = sz++;//新建结点
}
u = ch[u][c];//往下走
val[u]++;//字符串结点附加条件
}
va
}
int Find(char* s)
{
int flag = 0;
int u = 0,n = strlen(s);
int c;
for(int i =0; i<n; i++)
{
c = idx(s[i]);
if(!ch[u][c]) return 0;
if(i+1==n)break;
u = ch[u][c];
}
return val[ch[u][c]];
}
}A;
这里的代码我都解释了,最开始的时候呢,我是不会写find函数的哎,好渣,还是特意搜的····百度一下你就知道····,还差一个删除功能·····,容我想想。
接下来我贴一个动态的字典树,以前照模板打的
#include<iostream> #include<string> #include<cstdio> using namespace std; struct node { int v; node *next[26]; }; node *root; char str[50002][50]; void insert(char *s) { node *p=root; for(; *s!='\0'; s++) { int d=*s-'a'; if(p->next[d]==NULL) { p->next[d]=new node(); p=p->next[d]; } else p=p->next[d]; } p->v=1; } int search(char *s) { node *p=root; for(;*s!='\0';) { int d=*s-'a'; if(p->next[d]!=NULL) { p=p->next[d]; if(p->v==1) return 1; s++; } else return 0; } return 0; }
当然了,如果对于新手来说,我推荐·····我也不知道了···随便哪种方法,只要明白了,建树,查找,还有释放存储空间。。。