给定一个字符串S和有效单词的字典D,请确定可以插入到S中的最小空格数,使得最终的字符串完全由D中的有效单词组成。并输出解。
如果没有解则应该输出n/a
例如:
输入:
S = “ilikealibaba”
D = {"i","like","ali","liba","baba","alibaba"}
输出:
“i like alibaba”
解释:
字符串S可能被字典D这样拆分
"i like ali baba"
“i like alibaba”
很显然,第二个拆分结果是空格数最少的解。
思路:
目前只实现了最朴素的回溯法,复杂度可能有点儿高。需要剪枝策略,暂时未实现,待更新。
用start代表从字符串str的start位置开始,遍历中间结果,如果子串str.substr(start,i-start+1)在字典里面继续递归查找。
如果start已经到str末尾,则递归结束,将此时的结果temp保存到ret中。
最后遍历ret,返回ret中字符串个数最少的结果即为所求。
void mincut(int start,const string& str, const set<string>& dict,vector<vector<string>>& ret,vector<string>&temp) { if(start>=str.length()) { ret.push_back(temp); return; } string a; for(int i=start;i<str.length();i++) { a = str.substr(start,i-start+1); if(dict.find(a) == dict.end() )continue; temp.push_back(a); mincut(i+1,str,dict,ret,temp); temp.pop_back(); } } void mincut(const string& str, const set<string>& dict) { vector<vector<string>> ret; vector<string> temp; vector<string>result; mincut(0,str,dict,ret,temp); int min_size = str.size()+1, index =-1; for(int i=0;i<ret.size();i++)//找到最少字符串的结果 { if(min_size >ret[i].size()) { min_size = ret[i].size(); index = i; } } if(index!=-1)result = ret[index]; else { cout<<"n\a"<<endl; return; } for(int i=0;i<result.size();i++) { if(i==0)cout<<result[i]; else cout<<" "<<result[i]; } cout<<endl; } int main() { string str = "ilikealibaba"; set<string>dict = {"i","like","ali","liba","baba","alibaba"}; mincut(str,dict); }