poj1451~T9~字典树

本文介绍了一种利用字典树进行字符串匹配的方法,并详细解释了如何构建字典树及其实现过程。通过实例展示了如何将字符串及其对应的概率插入到字典树中,并通过输入数字序列来查找最大概率的字符串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近陷入了迷茫期和瓶颈期,不知所措,浑浑噩噩,好无斗志,哎哎哎,这个解析先放着先,好累……不知道自己的未来在何处

#include<iostream>
#include<string>
#include<fstream>
using namespace std;
#define MAX 8
char str[1001][101];
int  cou[1001][101];
int book[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
char b[100];

typedef struct Trie     //字典树
{
	Trie *next[8];     //八个按键
	int pmax;        //这个结点中的最大概率
	char word[101];   //对应的最大概率的那个串
};

Trie *root;

void insertTrie(char *str,int k) //构建字典树
{
	int len=strlen(str);
	Trie *p=root,*q;
	char temp[105];

	for(int i=0;i<len;i++)
	{	
		strcpy(temp,str);  //这个tmep后来用来表示一个串  
		int id=book[str[i]-'a']-2;
		
		if(p->next[id]==NULL)
		{
				
			q=new Trie;        
			for(int j=0;j<MAX;++j)
			{
				q->next[j]=NULL;
			}
			q->pmax=0;
			p->next[id]=q;
			p=p->next[id];
				
		}
		else 
		{
			p=p->next[id];
		}

		temp[i+1]='\0';     //给节点里放上最大概率的那个串
		if(cou[k][i]>p->pmax)
		{
			p->pmax=cou[k][i];
			strcpy(p->word,temp);
		}

	}
}

void findTrie(char *b)
{
	int len=strlen(b)-1;  //因为结尾是1,所以要减掉一个
	char st;
	int flag=1;
	Trie *p=root;
	for(int i=0;i<len;i++)
	{
		int id=b[i]-'0'-2;
		if(p->next[id]!=NULL&&flag) p=p->next[id];  
		else 
		{
			cout<<"MANUALLY"<<endl;    //如果节点是空的或者之前已经出现不存在的情况,则退出
			flag=0;
			continue;
		}
		cout<<p->word<<endl;
	}
}

int dealTrie(Trie *T)  //删除空间操作
{
	int i;
	if(T==NULL)
		return 0;
	for(i=0;i<MAX;i++)
	{
		if(T->next[i]!=NULL)
			delete T->next[i];
	}
	free(T);
	return 0;
}
int main()
{
	int t,n,pro,i,ii,j;
	cin>>t;
	for(j=1;j<=t;j++)
	{	
		root=new Trie;
		for(i=0;i<MAX;i++)
			root->next[i]=NULL;

		scanf("%d",&n);
		for(i=0;i<n;i++)
		{
			scanf("%s%d",str[i],&pro);
			for(ii=0;str[i][ii];ii++)    //每个前缀串的概率
				cou[i][ii]=pro;

			if(i>0)                
			{
				for(ii=0;str[i][ii]&&str[i-1][ii];ii++)  //如果发现前面有一样的前缀串,概率相加
					if(str[i][ii]==str[i-1][ii])
					{
						cou[i][ii]+=cou[i-1][ii];
						cou[i-1][ii]=0;
					}
					else break;
			}
            
			insertTrie(str[i],i);
		}

		printf("Scenario #%d:\n",j);
		scanf("%d",&n);
		for(i=0;i<n;i++)
		{
			int ii=0;
			scanf("%s",b);
			findTrie(b);
			cout<<endl;
		}
		cout<<endl;
		dealTrie(root);
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值