1. 程式人生 > >8.複合詞(UVA10391)

8.複合詞(UVA10391)

複合詞(UVA10391)

題目簡單分析

題目的詳細內容可以在這個網站上看到,下面簡單說明一下題目要求。
[題意]
本題主要任務是對於給出的一個詞典,找出裡面可有其他兩個單詞組合成的組合詞, 如newborn可由new和born組合而成。
[輸入輸出]
Sample Input:

a
alien
born
less
lien
never
nevertheless
new
newborn
the
zebra

Sample Output:

alien
newborn

[分析]
很容易看出來,這個題有兩類解法:一種是將所有單詞兩兩進行拼接

,然後將拼接的結果在詞典裡進行查詢。另一種方法是對每個單詞進行分割,將分割後的兩個單詞在詞典裡進行查詢。

由於題目要求最大單詞數為120000,所以肯定需要考慮耗時問題。假設採用拼接策略,則時間複雜度為O(n^2);而如果採用分割策略,則時間複雜度為O(n*m),其中m為單詞的平均長度減1。

從上面分析可知,當單詞的平均長度m<n時,分割策略更優。

此外,為了提高查詢速度,這裡採用了STL中的map來儲存單詞。

程式碼

下面是採用分割策略的AC程式碼,採用拼接策略的程式碼提交後超時這裡就不給出了。
注:C++版本為C++11,VScode的工程在github。程式碼如有bug,敬請指出。

#include <iostream>
#include <map>
#include <string>
using namespace std;

map<string, bool> map1;
string s[121000];
int main(){
    string str1, str2;
    int cnt=0;
    while(cin >> s[cnt]){
        map1[s[cnt]]=true;
        cnt++;
    }
    for(int i=0;i<cnt;++i)
        for
(int j=0;j<s[i].size();++j){ str1=s[i].substr(0, j+1); str2=s[i].substr(j+1); if(map1[str1] && map1[str2]){ cout << s[i] << endl; break; } } return 0; }