2011-01-20 132 views
3

下周我一直在练习C++进行比赛。在我一直在处理的示例问题中,需要将段落拆分为单词。当然,这很容易。但是这个问题很奇怪,像isn't这样的词也应该分开:isnt。我知道这很奇怪,但我必须遵循这一点。在C++中分隔字母字符STL

我有一个功能split()需要一个constant char定界符作为参数之一。这是我用来分隔空间的单词。但我无法弄清楚这一点。偶数如:phil67bs应该分开为philbs

不,我不要求完整的代码。一个伪代码会做,或者会帮助我理解该做什么。谢谢!

PS:请不要为外部库提供建议。只是STL。 :)

+1

“我知道这很奇怪” - 它不是(取决于算法的上下文)。 – 2011-01-20 13:18:55

回答

0

只是改变你的功能来界定任何不是字母字符。有什么特别的,你有麻烦吗?

分解问题:首先,编写一个函数,从句子中获取第一个“单词”。这很容易;只要寻找第一个非字母字符。下一步是从剩余字符串中删除所有前导非字母字符。从那里,只需重复。

+0

该函数使用`getline()`,它使用`const char`作为分隔符。如果我会做这么多'split()`语句,那将会非常困难。 – LOLcode 2011-01-20 13:17:59

0

你可以做这样的事情:

vector<string> split(const string& str) 
{ 
    vector<string> splits; 

    string cur; 
    for(int i = 0; i < str.size(); ++i) 
    { 
     if(str[i] >= '0' && str[i] <= '9') 
     { 
      if(!cur.empty()) 
      { 
       splits.push_back(cur); 
      } 
      cur=""; 
     } 
     else 
     { 
      cur += str[i]; 
     } 
    } 
    if(! cur.empty()) 
    { 
     splits.push_back(cur); 
    } 

    return splits; 

} 
1

这听起来像是为find_first_of功能,找到一组字符中第一次出现一个完美的工作。您可以使用它来查找任意停止字符并从停止字符之间的空格中生成单词。

大致为:

size_t previous = 0; 
for (; ;) { 
    size_t next = str.find_first_of(" '1234567890", previous); 
    // Do processing 
    if (next == string::npos) 
     break; 
    previous = next + 1; 
}; 
4

筛选出数字,空格和其他任何不使用正确的语言环境的一封信。请参阅this关于将数字视为空白处理所有内容的SO线程。所以使用mask并做类似的东西是什么杰里棺材建议但仅限于信件:

struct alphabet_only: std::ctype<char> 
{ 
    alphabet_only(): std::ctype<char>(get_table()) {} 

    static std::ctype_base::mask const* get_table() 
    { 
     static std::vector<std::ctype_base::mask> 
      rc(std::ctype<char>::table_size,std::ctype_base::space); 

     std::fill(&rc['A'], &rc['['], std::ctype_base::upper); 
     std::fill(&rc['a'], &rc['{'], std::ctype_base::lower); 
     return &rc[0]; 
    } 
}; 

而且,咚!你是金。

或者......你可以只是做一个转变:

char changeToLetters(const char& input){ return isalpha(input) ? input : ' '; } 

vector<char> output; 
output.reserve(myVector.size()); 
transform(myVector.begin(), myVector.end(), insert_iterator(output), ptr_fun(changeToLetters)); 

其中,嗯,是很容易神交,只是没有杰里的想法一样高效。

编辑:

更改的 'Z' 到 '[' 以使该值 'Z' 被填充。同样用'z'到'{'。

+0

您忘记更改语言环境的名称。否则,非常好的答案,学到了一些新东西(但为什么你在第二个例子中使用`std :: list`?这太可怕了)。 – 2011-01-20 13:53:52

+0

@Konrad Rudolph你说得对,我会将其改为向量。 – wheaties 2011-01-20 14:34:27

0

假设输入是在std::string(使用std::getline(cin, line)例如从cin阅读全行)

std::vector<std::string> split(std::string const& input) 
{ 
    std::string::const_iterator it(input), end(input.end()); 
    std::string current; 
    vector<std::string> words; 
    for(; it != end; ++it) 
    { 
    if (isalpha(*it)) 
    { 
     current.push_back(*it); // add this char to the current word 
    } 
    else 
    { 
     // push the current word in to the result list 
     words.push_back(current); 
     current.clear(); // next word 
    } 
    } 
    return words; 
} 

我没有测试它,但我想它应该工作...