将字符串拆分为单词

时间:2011-01-21 03:41:33

标签: algorithm string dictionary word substring

我正在寻找最有效的算法来形成字符串中所有可能的单词组合。例如:

Input String: forevercarrot

Output:

forever carrot
forever car rot
for ever carrot
for ever car rot

(所有单词都应该来自字典)。

我可以想到一种蛮力的方法。 (找到所有可能的子串并匹配)但是更好的方法是什么?

4 个答案:

答案 0 :(得分:6)

使用prefix tree作为已知字词列表。可能像myspell这样的库已经这样做了。尝试使用现成的。

一旦你找到一个匹配(例如'car'),就分开计算:一个分支开始寻找一个新词('rot'),另一个分支继续探索当前开头的变种('carrot')。

每次分割计算时,有效地在字符串中维护一对(start_position, current_position)个偏移的队列。多个线程可以并行地从此队列中弹出,并尝试继续从start_position开始并且已经知道该对的current_position的单词,但不会在那里结束。找到某个单词时,会报告该单词,并从队列中弹出另一对。当它不可能时,不会产生任何结果。发生拆分时,会在队列末尾添加一对新对。最初,队列包含(0,0)

答案 1 :(得分:1)

看到这个问题有更好的答案。这是一个标准的动态编程问题:

How to split a string into words. Ex: "stringintowords" -> "String Into Words"?

答案 2 :(得分:0)

一个伪代码实现,利用字符串的每个部分都需要成为一个单词的事实,我们不能跳过任何东西。我们从字符串的开头向前工作,直到第一个字为单词,然后生成字符串其余部分的所有可能组合。一旦我们完成了这个,我们会继续前进,直到找到第一个单词的任何其他可能性,依此类推。

allPossibleWords(string s, int startPosition) {
    list ret
    for i in startPosition..s'length
        if isWord(s[startPosition, i])
            ret += s[startPostion, i] * allPossibleWords(s, i)
    return ret    
}

此代码中的问题是,您最终会重复计算 - 在您的示例中,您最终必须计算allPossibleWords("carrot")两次 - 一次在["forever", allPossibleWords["carrot"]],一次在{{1 }}。所以要记住这一点是需要考虑的事情。

答案 3 :(得分:0)

输入字符串:forevercarrot

输出:

永远胡萝卜 永远的车腐烂 永远胡萝卜 因为汽车腐烂

程序:

#include<iostream>
#include<string>
#include<vector>
#include<string.h>
void strsplit(std::string str)
{
   int len=0,i,x,y,j,k;
   len = str.size();
   std::string s1,s2,s3,s4,s5,s6,s7;
   char *c = new char[len+1]();
   char *b = new char[len+1]();
   char *d = new char[len+1]();
   for(i =0 ;i< len-1;i++)
   {
       std::cout<<"\n";
       for(j=0;j<=i;j++)
       {
          c[j] = str[j];
          b[j] = str[j];
          s3 += c[j];
          y = j+1;
       }
       for( int h=i+1;h<len;h++){
          s5 += str[h];
       }
       s6 = s3+" "+s5;
       std::cout<<" "<<s6<<"\n";
       s5 = "";
       for(k = y;k<len-1;k++)
       {
          d[k] = str[k];
          s1 += d[k];
          s1 +=  " ";
          for(int l = k+1;l<len;l++){
           b[l] = str[l];
           s2 += b[l];
         }
       s4 = s3+" "+s1+s2;
       s7 = s4;
       std::cout<<" "<<s4<<"\n";
       s3 = "";s4 = "";
       }
       s1 = "";s3 = "";
    }
}

int main(int argc, char* argv[])
{
    std::string str;
    if(argc < 2)
                std::cout<<"Usage: "<<argv[0]<<" <InputString> "<<"\n";
    else{
                str = argv[1];
                strsplit(str);
    }

return 0;
}