是否有标准算法复制到?

问题描述 投票:1回答:3

我正在使用istream_iterator<char> it,所以我不能反向迭代该范围(或迭代两次,没有大量的hastle。)

我想复制,直到满足条件。在标准库中是否有类似的东西:

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++;
}
c++ algorithm copy range standard-library
3个回答
3
投票

仅仅为了完整性,由于标准没有提供开箱即用的解决方案,这是我的解决方案:

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

2
投票

开箱即用之前没有副本。因为你是从istream复制的,所以除了使用带有break语句的循环之外别无选择。


0
投票

http://en.cppreference.com/w/cpp/algorithm提供了对C ++中所有可用算法的非常有用的参考(不仅仅是算法库中的算法,还包括数值,内存和CStd库。)以下是复制算法,即它们采用输入迭代器。 ,输出迭代器和lambda(s)作为参数:

  • copy_if“复制范围内的元素,由[firstlast定义] ...仅复制谓词pred返回true的元素”
  • transform“将给定函数应用于范围并将结果存储在另一个范围内。”
  • remove_copy_if“将范围[firstlast]中的元素复制到d_first开始的另一个范围,省略满足特定标准的元素”
  • replace_copy_if“将范围[firstlast]中的所有元素复制到另一个范围,从d_first开始,用new_value替换满足特定标准的所有元素”
  • unique_copy“将范围[firstlast]中的元素复制到d_first开始的另一个范围,使得没有连续的相等元素......使用给定的二元谓词p比较元素”
  • partition_copy“将范围[firstlast]中的元素复制到两个不同的范围,具体取决于谓词p返回的值。满足谓词p的元素将被复制到从d_first_true开始的范围。其余元素被复制到从d_first_false开始的范围“
  • merge 需要第二个输入范围
  • set_difference 需要第二个输入范围
  • set_intersection 需要第二个输入范围
  • set_symmetric_difference 需要第二个输入范围
  • set_union 需要第二个输入范围
  • adjacent_difference“计算范围[firstlast]中每个相邻元素对的第二个和第一个之间的差异...使用给定的二元函数op计算差异”
  • partial_sum“计算范围[firstlast]子范围内元素的部分和,并将它们写入从d_first开始的范围......为了总结元素,第二个版本使用给定的二元函数op。”
  • exclusive_scan“使用binary_op计算范围[firstlast]的独占前缀和运算”
  • inclusive_scan“使用binary_op计算包含前缀和操作的范围[firstlast]”
  • transform_exclusive_scan“使用first转换范围[lastunary_op]中的每个元素,然后在结果范围内使用binary_op计算排他前缀和运算”
  • transform_inclusive_scan“使用first转换范围[lastunary_op]中的每个元素,然后在结果范围内使用binary_op计算包含前缀和运算”

因为lambda仅用于修改范围[firstlast]的1:1赋值给d_first; transformreplace_copy_if和所有数值库算法都没有用(adjacent_differencepartial_sumexclusive_scaninclusive_scantransform_exclusive_scantransform_inclusive_scan。)

  • 如果在满足lambda条件后,范围的其余部分[itistream_iterator<char>()]将被直接应用于第二个输出迭代器,partition_copy将解决您的问题
  • 如果在满足lambda条件之后,范围的其余部分[itistream_iterator<char>()]将由函数迭代,则在copy_if(或remove_copy_ifunique_copy)满足条件后,可以在每个值上调用此函数
  • 但在一般情况下,你的问题的答案是标准算法不提供“copy_until”所以你需要使用你的while循环
© www.soinside.com 2019 - 2024. All rights reserved.