一尘不染

选择性迭代器

algorithm

仅供参考:没有助益,是的,我 重新发明轮子;)

C ++中是否存在某种形式的选择性迭代器(可能)?我想要的是这样分隔字符串:

some:word{or other

变成这样的形式:

some : word { or other

我可以通过两个循环以及find_first_of(“:”)和(“
{”)来做到这一点,但这对我来说似乎效率很低。我认为也许会有一种创建/定义/编写迭代器的方法,该迭代器将使用for_each遍历所有这些值。我担心这会让我为std
:: string写一个成熟的自定义方式过于复杂的迭代器类。

所以我想也许这样做可以:

std::vector<size_t> list;
size_t index = mystring.find(":");
while( index != std::string::npos )
{
    list.push_back(index);
    index = mystring.find(":", list.back());
}
std::for_each(list.begin(), list.end(), addSpaces(mystring));

在我看来,这看起来很混乱,而且我很确定存在一种更优雅的方法。但是我想不到。有人有个好主意吗?谢谢

PS:我没有测试发布的代码,只是快速写了我会尝试的代码

更新:在考虑了您所有的答案之后,我想到了这一点,并且按我的喜好:)。这样做假设最后一个字符是一个新行或东西,否则结局{}:将不会得到处理。

void tokenize( string &line )
{
    char oneBack = ' ';
    char twoBack = ' ';
    char current = ' ';
    size_t length = line.size();

    for( size_t index = 0; index<length; ++index )
    {
        twoBack = oneBack;
        oneBack = current;
        current = line.at( index );
        if( isSpecial(oneBack) )
        {
            if( !isspace(twoBack) ) // insert before
            {
                line.insert(index-1, " ");
                ++index;
                ++length;
            }
            if( !isspace(current) ) // insert after
            {
                line.insert(index, " ");
                ++index;
                ++length;
            }
        }
    }

像往常一样欢迎评论:)


阅读 237

收藏
2020-07-28

共1个答案

一尘不染

std::string const str = "some:word{or other";

std::string result;
result.reserve(str.size());
for (std::string::const_iterator it = str.begin(), end = str.end();
     it != end; ++it)
{
  if (isalnum(*it))
  {
    result.push_back(*it);
  }
  else
  {
    result.push_back(' '); result.push_back(*it); result.push_back(' ');
  }
}

插入版本以加快速度

std::string str = "some:word{or other";

for (std::string::iterator it = str.begin(), end = str.end(); it != end; ++it)
{
  if (!isalnum(*it))
  {
    it = str.insert(it, ' ') + 2;
    it = str.insert(it, ' ');
    end = str.end();
  }
}

请注意,std::string::insert在传递迭代器之前插入,然后将迭代器返回到新插入的字符。分配很重要,因为缓冲区可能已被重新分配到另一个内存位置(迭代器因插入而无效)。另请注意,您无法保留end整个循环,每次插入时都需要重新计算。

2020-07-28