trie使用

#include<bits/stdc++.h>
using namespace std;
int trie[100001][26],k;
//trie树的数组表示形式,其中k表示当前这棵树所有的节点数
bool col[100001];//记录终止的位置 

/*模板
Type function(char *s)
{
  int len =s.length(),p=0;
  for(int i=0;i<len;i++)
  {
  	char c = s[i] - x;//x为最小可能的字符
	//do sth ...
	p= trie[p][c]; 
  }
  //do sth...
}
*/ 


//插入
//记录小写字母的trie树 
void insert_trie(char* s)
{
	int len = strlen(s),p=0;
	for(int i=0;i<len;i++)
	{
		char c=s[i]-'a';//直接定位到该节点所对应的相应路径上 
		if(!trie[p][c])
		trie[p][c] = ++k;//如果没有该路径,则新生成一个节点,将节点数加1处理
		//实现给树中的节点编号 
		p = trie[p][c];//定位到下一个节点 
	}
	col[p]=1;//标记好结束的节点 
 } 
 
 //查询是否存在该字符串
bool search_trie(char *s)
 {
 	int len=strlen(s),p=0;
 	for(int i=0;i<len;i++)
 	{
 		int c=s[i] - 'a';
 		if(!trie[p][c])
 		return false;//不存在相应的边,表示没有这个单词
        p=trie[p][c]; 
	 }
	 if(col[p])
	 return true;
	 else
	 return false; 
  } 


//删除相应的单词操作
bool delete_trie(char *s)
{//为了降低时间复杂度,并不调用search函数来判断对应的单词是否存在
 
 //需要考虑分叉问题 ,删除到上一个分叉的地方 
	
	int len=strlen(s),p=0;
	int flag=0; 
	int pre_num=0;//记录前面对应节点的位置 
	for(int i=0;i<len;i++)
	{
		int c=s[i] - 'a';
		if(!trie[p][c])
		return false;//不存在相应的边 ,无删除的单词 
		int cnt=0;
		for(int j=0;j<26;j++)
		{
			if(trie[p][j])
			cnt++;
		 }
		 if(cnt>1)
		 pre_num=p;
		if(col[p])
		pre_num=p;//字串 
		p=trie[p][c];
	 }
	 //继续向后遍历
	 //只需要看一看删除单词后面是否还有边
	 //删除的单词是否为字串 
	 if(!col[p])
	 return false;//结束位置没有标记 ,没有删除的单词 
	 for(int i=0;i<26;i++)
	 {
	 	if(trie[p][i])
	 	{//后面还有边 
	 	 //删除的单词为字串
		 //将结束位置抹掉 
		 flag=1;
		 }
	  } 
	  if(flag)
	  col[p]=0;//删除结束
	  else
	  {//从pre_num一直删到单词结束 
	    p=pre_num;
	  	for(int i=pre_num;i<len;i++)
	  	{  int c=s[i] - 'a';
	  	   trie[p][c]=0;
	  	   p=trie[p][c];
		  }
		col[p]=0;//把标记结束的位置删掉 
	   } 
 } 
int main()
{
	FILE *fp=fopen("trie_test.txt","r");
	if(!fp)
	{
		cout<<"file open error!"<<endl;
	}
	else
	{
		cout<<"file open successfully!"<<endl;
	}
	char buff[1000];
	while(fgets(buff,1000,fp)!=NULL)
	{
		char *temp=strtok(buff,"\n");//去除读入的换行符
		insert_trie(temp); 
	}
	char test[]="bttopeses";
	char test2[]="bttob";
	if(search_trie(test))
	cout<<"find successfully!"<<endl;
	else
	cout<<"not find!" <<endl;
	delete_trie(test);
	if(search_trie(test2))
	cout<<"find successfully!"<<endl;
	else
	cout<<"not find!" <<endl;
	return 0;
 } 
 

  

posted @ 2020-07-29 16:48  zmachine  阅读(142)  评论(0)    收藏  举报