选择性迭代器
问题内容:
仅供参考:没有助益,是的,我 想 重新发明轮子;)
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;
}
}
}
像往常一样欢迎评论:)
问题答案:
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
整个循环,每次插入时都需要重新计算。