【題目描述】
最近國安人員截獲了一份 RB 國的秘密情報, 全文都是經過加密的,每個單 詞都很長。破譯人員想到先把單詞化簡一下,方法是把每個單詞盡量取短些的前 綴,但所取的前綴不能是其他單詞的前綴。 這個任務現在就交給你來完成。
解釋:“字符串s1是s2的前綴”意思是把字符串s2的后面去掉某些字符,只保留與s1相同長度的子串,則s1就稱為s2的前綴。如:“abc”是“abcaade”和“abc”的 前綴,但不是“abadc”的前綴。
數據范圍 單詞數 N, 1<=n<=50; 每個單詞長度不超過 50;並且都是由小寫字母構成。 保證所給單詞沒有一個單詞是另一個單詞的前綴。
【輸入文件 addreviate.in】
第一行一個整數 N,表示單詞的個數。 下面有 N 行,每行一個單詞。
【輸出文件 addreviate.out】
共 N 行,每行一個單詞,是對應上面 N 個單詞化簡后的單詞。
【樣例輸入】
樣例測試點#1:
3
abc
efg
ijh
樣例測試點#2:
3
aac
aad
aae
【樣例輸出】
樣例測試點#1:
a
e
i
樣例測試點#2:
aac
aad
aae
思路:這題算是送分題中的高難度題了,對於各位高手來說不是什么問題,我說這題是為了提一下一個庫函數,這個庫函數是我們一般不經常用的,廢話不多說,我先從頭講起吧
這題要求我們保留n個字符串的前綴,使得這些前綴和其他前綴不相同,縮小存儲空間,看起來很簡單,其實還是有點復雜滴
例如題目中給的樣例:可以先把第一個字符按照圖中紅線分段,提取第一行第一個字符,來和下面的每一個字符串進行對比
,如果這個段並不在下面任何一個字符串中是前綴,就可以在后面加上個'\0'表示截取這一段
之后對每一行都采取這樣的措施,就可以實現保留前綴
代碼如下:
1 #include <stdio.h> 2 #include <string.h> 3 int main() 4 { 5 //freopen("addreviate.in","r",stdin); 6 //freopen("addreviate.out","w",stdout); 7 char a[51][51],temp; 8 int n; 9 int i,j,k; 10 int flag,len; 11 scanf("%d",&n); 12 for(i=0;i<n;i++) 13 { 14 scanf("%s",a[i]); 15 } 16 for(i=0;i<n;i++) 17 { 18 len=strlen(a[i]);//測一下a[i]的長度 19 for(k=1;k<len;k++)//掃描整個子串 20 { 21 temp=a[i][k];//記錄一下當前字符 22 a[i][k]='\0';//當前標記為空 23 for(j=0;j<n;j++) 24 { 25 if(i!=j&&(strstr(a[j],a[i])-a[j])==0)//如果不是同一行,並且這個子串與這個字符串的前面一部分吻合,就可以停止了 26 { 27 break;//停止!! 28 } 29 } 30 if(j>=n)//這個空的位置前面一段保證前綴不重復,就可以標記為空了 31 { 32 a[i][k]='\0'; 33 break; 34 } 35 else//否則還要還原回去,繼續尋找下一位 36 { 37 a[i][k]=temp; 38 } 39 } 40 } 41 for(i=0;i<n;i++) 42 { 43 printf("%s\n",a[i]); 44 } 45 return 0; 46 }