Shortest Prefixes

链接:http://acm.hust.edu.cn/vjudge/problem/11157/origin

题目:A prefix of a string is a substring starting at the beginning of the given string. The prefixes of "carbon" are: "c", "ca", "car", "carb", "carbo", and "carbon". Note that the empty string is not considered a prefix in this problem, but every non-empty string is considered to be a prefix of itself. In everyday language, we tend to abbreviate words by prefixes. For example, "carbohydrate" is commonly abbreviated by "carb". In this problem, given a set of words, you will find for each word the shortest prefix that uniquely identifies the word it represents.

In the sample input below, "carbohydrate" can be abbreviated to "carboh", but it cannot be abbreviated to "carbo" (or anything shorter) because there are other words in the list that begin with "carbo".

An exact match will override a prefix match. For example, the prefix "car" matches the given word "car" exactly. Therefore, it is understood without ambiguity that "car" is an abbreviation for "car" , not for "carriage" or any of the other words in the list that begins with "car".

题意:给出几个单词,要求对每个单词找出足以从所给的单词中区分出他的前缀。如果某个单词a就是别的单词b的前缀,那么他自己a代表自己。

分析:总的来说就是除了那个特殊情况外,找到最小的公公前缀在加上一个单词。这种互相区分匹配的问题最好的解决办法是字典树。为了解决这个问题,我们其实就是再找每个单词在树状数组的路径上直到这条分支上只有自己这一个单词时的最短路径。所以用一个n来维护当前结点之后有几个单词,查找的时候判断,只要n==1了,ok前缀找到了。

题解:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define rt return
#define fr freopen("in.txt","r",stdin)
#define fw freopen("out.txt","w",stdout)
#define ll long long
#define ull unsigned long long
#define detie ios_base::sync_with_stdio(false);cin.tie(false);cout.tie(false)
#define pii pair
#define lowbit(x) x&(-x)
using namespace std;
#define maxi 0x3f3f3f3f
#define MAX 1000100

string ss[1010];

struct Node 
{
	int count;
	Node* next[26];
	Node():count(0) { memset(next, 0, sizeof next); }
}*root;

void insert(string &s)
{
	int len = s.length();
	Node* p = root;
	for (int i = 0; i < len; i++)
	{
		int id = s[i] - 'a';
		if (!p->next[id])
			p->next[id] = new Node;
		p = p->next[id];
		p->count++;//注意count++的位置。。。。
	}
}

void find(string &s)
{
	int len = s.length();
	Node* p = root;
	for (int i = 0; i < len; i++)
	{
		int id = s[i] - 'a';
		cout << s[i];
		if (p->next[id])
		{
			p = p->next[id];
			if (p->count <= 1)
				break;
		}
	}
	cout << endl;
}


int main()
{
	//fr;
	detie;
	root = new Node;
	string t;
	int cnt = 0;
	while (cin >> t){
		ss[cnt++] = t;
		insert(t);
	}
	for (int i = 0; i < cnt; i++)
	{
		cout << ss[i] << ' ';
		find(ss[i]);
	}
	rt 0;
}

你可能感兴趣的:(字典树)