POJ 2001 - Shortest Prefixes (Trie树)

题目:http://poj.org/problem?id=2001

题意:

至少2组字符串,对于每个字符串,找出能识别它的最短前缀,如:abbdef,abcdef。“ab”它们为公共前缀,无法识别,所以对应最短识别前缀为:abb、abc

分析:

建立一棵节Trie树,节点存放单个字母,由根节点到子叶的一条路径为,出现过的单词。加入单词时候,各节点数中值+1,表示该前缀共有次数,最后找到第一个值为1个前缀,即可表示最短识别前缀

代码:

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>

using namespace std;

#define MAX 1000+10
#define MIN -1e+10
#define INF 0x7f7f7f7f

int t, n, m;

struct Trie
{
	int id; // 该前缀(由当前字母到根节点的路径)出现次数
	Trie *child[26]; // 下一字母节点
	Trie()
	{
		memset(child, 0, sizeof(child));
		id = 0;
	}
} root;

void insert(char str[]) // 插入一个单词,更新维护一条路径
{
	Trie *x = &root;
	for(int i = 0; str[i]; i++) // 逐个插入
	{
		if(x->child[str[i]-'a'] == NULL) // 该前缀未出现过
		{
			Trie *p = new Trie;
			x->child[str[i]-'a'] = p;
			x = p;
		}
		else x = x->child[str[i]-'a']; // 该前缀已经存在

		x->id++; // 该前缀出现次数+1
	}
}

void output(char str[]) // 输出一个单词的最短识别前缀
{
	Trie *x = &root;
	char str1[30], len = 0;
	for(int i = 0; str[i]; i++)
	{
		x = x->child[str[i]-'a']; // 向下查找前缀
		str1[len++] = str[i];
		if(x->id == 1) // 找到第一个出现次数为1的前缀,直接输出
			break;
	}
	str1[len] = '\0';
	printf("%s %s\n",str, str1);
}

int main()
{
	int i, j, k;
	freopen("a.txt", "r", stdin);

	char str[MAX][30];
	for(n = 0; ~scanf("%s", str[n]); n++)
	{
		insert(str[n]);
	}
	for(i = 0; i<n; i++)
	{
		output(str[i]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值