首页 > 技术文章 > 阿里校招内推C++岗位编程题第一题 空格最少的字符串

hellowooorld 2017-08-25 22:16 原文

给定一个字符串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);
}

 

推荐阅读