您的位置:首页 > 其它

字典树小结

2014-06-05 15:56 239 查看
字典树:

字典树 即Tire树,以一个空的头结点分若干的分支,来存放数据,虽浪费了大量内存,但是查找速度非常快。

匹配 时间复杂度 O(n) n = strlen(a);



字典树分 3步,建树、插入、查找

当然有时候,建树的选择是很重要的一点,尽量本着少往字典树上添加节点的原则,容易爆!!!

列入下面这题,用m建树,n来查找,即可AC,如果用n来建树,就会爆内存,所以建树的选择是很重要的一点

给定n个字符串,m个字符串,判断n中有多少个 是与m不一样的字符串。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
const int N = 20010;
using namespace std;

struct node{
int flag;//标记作用
node *next[26];
};
int n,m;
struct node *Creat()  //建树
{
node *p = new node;
for(int i = 0;i<26;i++)
{
p->next[i] = NULL;
}
p->flag = 0;
return p;
}

void INsert(node *root,char *b) //插入
{
int num;
int len = strlen(b);
node *p = root;
for(int i = 0;i<len;i++)
{
if(b[i]>='A' && b[i]<='Z')
num = b[i]-'A';
else
num = b[i]-'a';
if(p->next[num]==NULL)//如果为空,在当前节点的基础上在建树
{
p->next[num] = Creat();
}
p = p->next[num]; //指针移动到下一个节点
}
p->flag = 1;  //插入完成标记为1
}

int Search(node *root,char *b)  //查找
{
node *p = root;
int num;
int len = strlen(b);
for(int i = 0;i<len;i++)
{
if(b[i]>='A' && b[i]<='Z')
num = b[i] - 'A';
else
num = b[i]-'a';
if(p->next[num]==NULL) //不存在
return 0;
p = p->next[num];
}
if(p->flag==1) //找到
{
p->flag = 0;//预防重复查找
return 1;
}

return 0;
}
void FREE(struct node*root)
{
for(int i = 0;i<n;i++)
{
if(root->next[i]!=NULL)
{
FREE(root->next[i]);
}
}
free(root); root = NULL;

}
int main()
{
char a
[50],s[50];
node *p;
while(scanf("%d",&n),n)
{
scanf("%d",&m);
p = Creat();

for(int i = 0;i<n;i++)
{
scanf("%s",a[i]);
}

for(int i = 0;i<m;i++)
{
scanf("%s",s);
INsert(p,s);
}
int sum = 0;
for(int i = 0;i<n;i++)
{
sum += Search(p,a[i]);
}
printf("%d\n",n-sum);
FREE(p);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: