最短前綴

Description

一個字符串的前綴是從該字符串的第一個字符起始的一個子串。例如 "carbon"的字串是: "c", "ca", "car", "carb", "carbo", 和 "carbon"。注意到這裏我們不認爲空串是字串, 但是每個非空串是它自身的字串. 我們現在希望能用前綴來縮略的表示單詞。例如, "carbohydrate" 通常用"carb"來縮略表示. 現在給你一組單詞, 要求你找到唯一標識每個單詞的最短前綴 
在下面的例子中,"carbohydrate" 能被縮略成"carboh", 但是不能被縮略成"carbo" (或其餘更短的前綴) 因爲已經有一個單詞用"carbo"開始 
一個精確匹配會覆蓋一個前綴匹配,例如,前綴"car"精確匹配單詞"car". 因此 "car" 是 "car"的縮略語是沒有二義性的 , “car”不會被當成"carriage"或者任何在列表中以"car"開始的單詞.

Input

輸入包括至少2行,至多1000行. 每行包括一個以小寫字母組成的單詞,單詞長度至少是1,至多是20. 

Output

輸出的行數與輸入的行數相同。每行輸出由相應行輸入的單詞開始,後面跟着一個空格接下來是相應單詞的沒有二義性的最短前綴標識符。 

Sample Input

carbohydrate
cart
carburetor
caramel
caribou
carbonic
cartilage
carbon
carriage
carton
car
carbonate

Sample Output

carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona

Source

翻譯自Rocky Mountain 2004


//拿一個出來,另一個不包含,如果全部字符串都包含,那也沒辦法。
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

int main()
{
	char s[1002][22],tmp[22];
	int len[1002];
	int i,j,k,count=0;

	while((scanf("%s",s[count]))!=EOF)
	{
		len[count]=strlen(s[count]);
		count++;
	}

	for(i=0;i<count;i++)         //count個字符串,進行count次輸出
	{

		for(j=1;j<=len[i];j++)		//要想循環到每個字符
		{
			memset(tmp,0,sizeof(tmp));    //清零tmp數組
			for(k=0;k<j;k++)
				tmp[k]=s[i][k];  //用tmp存儲s[i]前j個字符,j在增加
			tmp[k]='\0';
			for(k=0;k<count;k++)   
			{
				if(k!=i)         //tmp存儲的就是s[i]的前j個字符, k!=i代表不和自己進行比較
				{
					if(strstr(s[k],tmp)==s[k])	//如果包含,則就會返回包含的子串,以及其後面的字符,在這裏的應用就是,若包含則返回總串
						break;                 //被包含了,則跳出k的循環。
				}
			}
			if(k==count)      //如果被統統比較了一遍,並且都沒有被包含,則可以進行輸出了
			{
				cout<<s[i]<<" "<<tmp<<endl;
				break;                //跳出j的循環,讓i++,表示已經完成一個單詞的最短前綴了
			}
		}

		if(j==len[i]+1)      //如果j循環完了,還是被包含了,那也沒有辦法了,只有輸出自己。
			cout<<s[i]<<" "<<s[i]<<endl;


	}
	return 0;
}

發佈了34 篇原創文章 · 獲贊 17 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章