(算法)最长单词
题目:
给定一组单词,找出其中的最长单词,且该单词由这组单词中的其他单词组成。
思路:
首选将单词按照字符串大小从大到小排序,然后依次判断该单词是否由其他单词组成。
将单词保存在散列表中,这样容易查找。
判断单词组成:依次切分为左右两个字符串,然后递归查找判断。(为避免重复计算,在每一次递归中都保存中间结果,即把是否可以组成单词的结果都保存在散列表中)
代码:
#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; }