ich*_*lus 7 c++ algorithm lambda iterator stl
我很难理解std::accumulate
。它可以用于仅对向量的偶数索引求和吗?
int rob(vector<int>& nums) {
int a = std::accumulate(nums.begin(), nums.end(), 0);
std::cout <<" a: " <<a;
return a;
}
Run Code Online (Sandbox Code Playgroud)
所以如果我有一个 vector y = {1, 2, 3, 4}
我如何更改上面的代码,以便std::accumulate
仅对索引[0]和[2]进行迭代。使用它甚至可能std::accumulate
吗?
你有几个选择。快速且(真正)肮脏的方法是遍历整个集合,并调用一个跟踪当前索引的函数,并忽略奇数索引处的值。它有效,但充其量是丑陋的,更重要的是,它在相当基本的层面上是错误的,迫使应该是累积函数的东西承担迭代的责任。简而言之,这与其说是一个解决方案,不如说是一个问题。
干净的方法是认识到访问集合中的所有其他项目实际上与迭代有关,而不是与特定算法(std::accumulate
或任何其他算法)有关。所以我们在这里应该使用一个迭代器来访问我们想要访问的项目。这是一个最小的实现:
#include <vector>
#include <iterator>
#include <iostream>
#include <numeric>
template <class Iterator>
class n_iterator {
Iterator i;
size_t n;
public:
// We construct this iterator from some other iterator, plus a "step" value
// to tell us how many items to skip forward when `++` is applied.
n_iterator(Iterator i, size_t n) : i(i), n(n) {}
// When you dereference this iterator, it's equivalent to dereferencing
// the underlying iterator.
typename std::iterator_traits<Iterator>::value_type operator *() { return *i; }
// ...but when you increment it, you move ahead N places instead of 1.
n_iterator &operator++() { std::advance(i, n); return *this; }
// iterator comparisons just compare the underlying iterators.
bool operator==(n_iterator const &other) const { return i == other.i; }
bool operator!=(n_iterator const &other) const { return i != other.i; }
};
int main() {
std::vector<int> y { 1, 2, 3, 4};
auto total = std::accumulate(y.begin(), y.end(), 0);
std::cout << "total: " << total << "\n";
auto skip_total = std::accumulate(n_iterator(y.begin(), 2), n_iterator(y.end(), 2), 0);
std::cout << "Skipped total: " << skip_total << "\n";
}
Run Code Online (Sandbox Code Playgroud)
这个实现似乎足以让 g++ 7.1 编译代码,但对于实际使用,您可能应该实现迭代器的整个接口(例如,至少,它应该真正具有 、value_type
等的定义reference
)
目前,这也仅提供一个前向迭代器,而不管底层迭代器是什么。根据情况(以及底层迭代器的类别),您还可以支持双向和/或随机迭代。