在C ++ STL中分隔字母字符

时间:2011-01-20 13:07:39

标签: c++ algorithm stl

我下周一直在练习C ++参加比赛。在我一直在研究的样本问题中,需要将段落分成单词。当然,这很容易。但是这个问题太奇怪了,像isn't这样的词也应该分开:isnt。我知道这很奇怪,但我必须遵循这一点。

我有一个函数split(),它将constant char分隔符作为参数之一。这就是我用来将空格分开的方法。但我无法弄清楚这个。即使是phil67bs这样的数字也应该分为philbs

不,我不要求完整的代码。伪代码会做,或者有助于我理解该怎么做的东西。谢谢!

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

5 个答案:

答案 0 :(得分:4)

使用适当的区域设置过滤掉数字,空格和其他任何非字母的内容。请参阅this SO线程,关于处理所有内容,但将数字视为空格。因此,使用mask并执行与Jerry Coffin建议的类似的操作,但仅限于字母:

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) );

哪个,嗯,更容易理解,只是没有Jerry的想法那么高效。

编辑:

将'Z'更改为'[',以便填充值'Z'。同样地,'z'到'{'。

答案 1 :(得分: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;
};

答案 2 :(得分:0)

只需更改您的函数即可分隔任何非字母字符的内容。你有什么特别的麻烦吗?

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

答案 3 :(得分: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;

}

答案 4 :(得分: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;
}

我没有测试过,但我想它应该有效......