是否有标准算法要复制直到
Is There a Standard Algorithm to Copy Until?
我正在使用istream_iterator<char> it
,所以我不能反向迭代范围(或迭代两次,没有太多的匆忙。
我想复制直到满足条件。在标准库中是否有这样工作的东西:
copy_until(it, istream_iterator<char>(), ostream_iterator<char>(cout), [](const unsigned char i){ return isalpha(i); })
如果我必须滚动一些我可以的东西,我只是希望一些我无法弄清楚的魔法。
编辑:
我期望从我编造的copy_until
函数中得到的行为是:
while(it != istream_iterator<char>()) {
if(!isalpha(static_cast<unsigned char>(*it))) break;
cout << *it++;
}
只是为了完整起见,由于该标准没有提供开箱即用的解决方案,这就是我的解决方案:
template<class _InIt, class _OutIt, class _Pr>
inline void copy_until (_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred) {
while ((_First != _Last) && _Pred(*_First)) {
*_Dest++ = *_First++;
}
}
这就是我使用它的方式:
copy_until(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(os),
[] (char c) { return <some usefull condition here> });
例如,要从输入流中读取仅包含 alnum 字符的字符串:
std::istream& operator>> (std::istream& is, std::string& n) {
std::ostringstream str;
copy_until(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(str),
std::isalnum);
n = str.str();
return is;
}
开箱即用之前没有副本。由于您是从 istream 复制的,因此除了使用带有 break 语句的循环之外别无选择。
http://en.cppreference.com/w/cpp/algorithm 提供对C++中所有可用算法(不仅是算法库中的算法,还包括数字、内存和CStd 库中的算法)的非常有用的参考。其中,以下是复制算法,即它们将输入迭代器、输出迭代器和 lambda 作为参数:
copy_if
"复制区域中的元素,由 [first
,last
) 定义...仅复制谓词pred
返回 true 的元素">transform
"将给定函数应用于一个范围并将结果存储在另一个范围中。remove_copy_if
"将元素从范围 [first
,last
) 复制到从d_first
开始的另一个范围,省略满足特定条件的元素">replace_copy_if
"将范围 [first
,last
) 中的所有元素复制到从d_first
开始的另一个范围,将所有满足特定条件的元素替换为new_value
">unique_copy
"将元素从范围 [first
,last
) 复制到从d_first
开始的另一个范围,这样就没有连续的相等元素......使用给定的二进制谓词p
比较元素
"partition_copy
"根据谓词p
返回的值,将元素从范围 [first
,last
) 复制到两个不同的范围。满足谓词p
的元素被复制到从d_first_true
开始的范围。其余元素被复制到从d_first_false
开始的范围">需要 2nd输入范围merge
需要 2nd输入范围set_difference
需要 2nd输入范围set_intersection
需要 2nd输入范围set_symmetric_difference
需要 2nd输入范围set_union
adjacent_difference
"计算范围 [first
,last
) 的每对相邻元素的第二个和第一个之间的差值......差值是使用给定的二进制函数op
计算
的"partial_sum
"计算范围 [first
,last
) 的子范围中元素的部分和,并将它们写入从d_first
开始的范围......为了总结这些元素,第二个版本使用给定的二进制函数op
.">exclusive_scan
"使用范围 [first
,last
的binary_op
计算独占前缀和运算">inclusive_scan
"使用范围 [first
last
的binary_op
计算包含前缀和运算">transform_exclusive_scan
"用unary_op
转换范围 [first
,last
) 中的每个元素,然后在结果范围内使用binary_op
计算一个独占前缀和运算">transform_inclusive_scan
"用unary_op
转换范围 [first
,last
) 中的每个元素,然后在结果范围内使用binary_op
计算包含前缀和运算">
因为 lambda 仅用于将范围 [first
,last
) 的 1:1 赋值修改为d_first
;transform
、replace_copy_if
和所有的数字库算法都是无用的(adjacent_difference
、partial_sum
、exclusive_scan
、inclusive_scan
、transform_exclusive_scan
和transform_inclusive_scan
)。
-
如果在满足 lambda 条件后,范围的其余部分 [
it
,istream_iterator<char>()
) 将直接复制到第 2个输出迭代器,partition_copy
将解决您的问题 -
如果在满足lambda条件之后,范围[
it
,istream_iterator<char>()
)的其余部分将由函数迭代,则在条件由copy_if
(或remove_copy_if
或unique_copy
)满足条件后,可以在每个值上调用此函数。 - 但在一般情况下,你的问题的答案是标准算法不提供"copy_until",所以你需要使用你的
while
循环。
copy_until
可以用std::find_if
来实现,std::copy
。
使用与 redleg 相同的结构,该算法可以首先搜索终止符,然后复制范围。
template <class _InIt, class _OutIt, class _Pr>
inline void copy_until(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred) {
_InIt _posTerm = std::find_if(_First, _Last, _Pred);
std::copy(_First, _posTerm, _Dest);
}
该模板需要<algorithm>
和<iterator>
。
下面是如何使用它的示例:
std::vector<int> source = {1,2,3,4,5,6,7,8};
std::vector<int> dest {};
copy_until(source.begin(),source.end(),
back_inserter(dest),[](int c) {return c == 5;});
输出:
source: 1 2 3 4 5 6 7 8
dest : 1 2 3 4
Beacusestd::copy
被定义为复制到最后,但不包括最后或其他术语[first,last)
,find_if
的位置不会被复制。
如果您需要一个包容性直到,这意味着[first,last]
,我们需要做更多的检查。如果终结者位于end()
则迭代器不应前进。
template <class _InIt, class _OutIt, class _Pr>
inline void copy_until(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pred)
{
_InIt _posTerm = std::find_if(_First, _Last, _Pred);
if (_posTerm != _Last ) { _posTerm++; }
std::copy(_First,_posTerm,_Dest);
}
前面的示例现在将输出:
source: 1 2 3 4 5 6 7 8
dest : 1 2 3 4 5
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 错误:在"模板"之前预期主表达式,具有算法的复制功能
- 使用 while 循环和搜索算法进行复制
- STL算法函数,如累加,如果传递给它们的函数接受引用,请避免复制
- 是否有标准算法要复制直到
- 具有四个迭代器的类似复制的算法
- 是否允许标准库算法复制谓词参数
- 使用复制算法在 C++ 中打印矢量的格式问题
- 使用ifstream复制算法
- 生成和复制矢量的STL算法
- 为什么序列运算算法谓词是通过复制传递的
- 使用back_inserter复制算法
- 使用c++标准库,复制算法
- 另一个复制算法
- c++复制直到算法
- 我可以使用复制算法复制'set'中的'vector'元素吗?
- 作用于可移动但不可复制对象序列的变化STL算法的行为