POJ 2001 Shortest Prefixes (字典树)

题目类型  字典树

题目意思
给出最多 1000 个最长 20 的字符串 问每个字符串可以准确识别的最短识别长度对应的字符串是什么
准确识别长度的意思是如果前这个长度的字符都匹配的话那么就肯定是这个字符串了(即没有其他字符串符合这个要求 除非那个字符串就只由这么多字符组成)

解题方法
字典树 
记录每个结点被遍历的次数 查询的时候当某个结点遍历次数为 1 即说明到这个结点为止已经可以识别了 如果一直都没碰到这样的结点说明整个字符本身是那个要求输出的字符串

参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define B printf("BUG\n");
const int maxnode = 20100 + 10;
const int sigma_size = 27;

char str[1010][sigma_size];

struct Trie {
	int ch[maxnode][sigma_size];
	int val[maxnode];
	int sz;
	Trie () { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }
	int idx(char c) { return c - 'a'; }

	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;
				ch[u][c] = sz++;
			}
			u = ch[u][c];
			val[u]++;
		}
	}

	int query(char * s) {
		int u = 0, n = strlen(s);
		for( int i=0; i<n; i++ ) {
			int c = idx(s[i]);
			u = ch[u][c];
			if(val[u] <= 1) return i+1;
		}
		return n;
	}
};

Trie t;
int main() {
	freopen("in", "r", stdin);
	int k = 0;
	while(cin.getline(str[k],30)) {
		t.insert(str[k]);
		k++;
	}
	for( int i=0; i<k; i++ ) {
		int len = t.query(str[i]);
		printf("%s ", str[i]);
		for( int j=0; j<len; j++ ) printf("%c", str[i][j]);
		printf("\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值