(算法)最长单词

题目:

给定一组单词,找出其中的最长单词,且该单词由这组单词中的其他单词组成。

思路:

首选将单词按照字符串大小从大到小排序,然后依次判断该单词是否由其他单词组成。

将单词保存在散列表中,这样容易查找。

判断单词组成:依次切分为左右两个字符串,然后递归查找判断。(为避免重复计算,在每一次递归中都保存中间结果,即把是否可以组成单词的结果都保存在散列表中)

代码:

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

bool canBuildWord(string &str,bool isOriginal,map<string,bool> &mp);

bool cmp(const string &str1,const string &str2){
    int len1=str1.size();
    int len2=str2.size();
    if(len1>len2)
        return true;
    return false;
}

string LongestWord(vector<string> &words){
    int n=words.size();
    string str;
    map<string,bool> mp;

    for(int i=0;i<n;i++)
        mp[words[i]]=true;

    sort(words.begin(),words.end(),cmp);    

    for(int i=0;i<n;i++){
        str=words[i];
        if(canBuildWord(str,true,mp)){
            //cout<<str<<endl;
            return str;
        }
    }
    return "";
}

// IsOriginal: indicate if str is the subString or not
bool canBuildWord(string &str,bool isOriginal,map<string,bool> &mp){
    if(mp.find(str)!=mp.end() && !isOriginal){
        mp[str]=true;
        return true;
    }

    int len=str.size();

    for(int i=1;i<len;i++){
        string left=str.substr(0,i);
        string right=str.substr(i,len-i);
        //cout<<left<<" "<<right<<endl;    
        if(mp.find(left)!=mp.end() && mp[left]==true && canBuildWord(right,false,mp))
            return true;
    }
    mp[str]=false;
    return false;
}

int main(){
    int n;
    while(cin>>n){
        vector<string> words(n);
        for(int i=0;i<n;i++)
            cin>>words[i];
        cout<< LongestWord(words) <<endl;
    }
    return 0;
}

 

posted @ 2015-10-26 19:47  AndyJee  阅读(918)  评论(0编辑  收藏  举报