仅在使用迭代器的某些索引上生成值
Acessing Values only at certain indexes using iterators
我很难理解std::accumulate
。它可以用来将向量中偶数索引的值相加吗?
int rob(vector<int>& nums) {
int a = std::accumulate(nums.begin(), nums.end(), 0);
std::cout <<" a: " <<a;
return a;
}
所以如果我有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";
}
这个实现似乎足以让 g++ 7.1 编译代码,但对于实际使用,你可能应该为迭代器实现整个接口(例如,至少,它应该真正具有value_type
、reference
等的定义(。
目前,这也只提供一个前向迭代器,而不考虑底层迭代器。根据情况(和底层迭代器的类别(,您还可以支持双向和/或随机迭代。
你来了
int rob( const vector<int>& nums) {
int i = 0;
int a = std::accumulate(nums.begin(), nums.end(), 0,
[&i]( const auto &acc, const auto &value )
{
return ( i ^= 1 ) ? acc + value : acc;
} );
std::cout <<" a: " <<a;
return a;
}
这是一个演示程序
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
int rob( const std::vector<int> &nums )
{
int i = 0;
int a = std::accumulate( std::begin( nums ), std::end( nums ), 0,
[&i]( const auto &acc, const auto &value )
{
return ( i ^= 1 ) ? acc + value : acc;
} );
return a;
}
int main()
{
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << rob( v ) << 'n';
return 0;
}
它的输出是
20
您可以向函数再添加一个参数,您可以选择是求和偶数还是奇数。例如
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
int rob( const std::vector<int> &nums, bool odds = false )
{
int i = odds;
int a = std::accumulate( std::begin( nums ), std::end( nums ), 0,
[&i]( const auto &acc, const auto &value )
{
return ( i ^= 1 ) ? acc + value : acc;
} );
return a;
}
int main()
{
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << rob( v ) << 'n';
std::cout << rob( v, true ) << 'n';
return 0;
}
程序输出为
20
25
在这种情况下,您可以删除变量 i 的声明。例如
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
int rob( const std::vector<int> &nums, bool odds = false )
{
int a = std::accumulate( std::begin( nums ), std::end( nums ), 0,
[&odds]( const auto &acc, const auto &value )
{
return ( odds = !odds ) ? acc + value : acc;
} );
return a;
}
int main()
{
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << rob( v ) << 'n';
std::cout << rob( v, true ) << 'n';
return 0;
}
相关文章:
- 跟随整数索引列表的自定义类迭代器
- 为什么 min_element() 返回最小元素的索引,而不是迭代器?
- 在擦除或修改作为不同索引键的值时,boost::multi_index 迭代器是否无效?
- C++将向量迭代器转换为索引
- 使用索引与迭代器将向量迭代到倒数第二个元素
- 如何使equal_range迭代器在 Boost 多索引中按不同的索引排序?
- 仅在使用迭代器的某些索引上生成值
- 是否可以在C++中获得索引迭代器?
- 有没有办法创建一个花哨的迭代器和相应的新数组,以便检查每个索引的索引值的条件?
- 索引与迭代器 - 哪个更有效?
- C 迭代器比索引慢得多
- 存储Boost Multi_index索引迭代器
- 属性树常量迭代器的索引
- 矢量迭代器的索引
- 提升多索引有序迭代器分配
- 使用迭代器的矢量擦除特定索引(不基于范围或条件)
- 为什么boost多索引返回错误的迭代器
- 从迭代器获取索引处的元素
- Deque索引迭代器转换
- Boost C++ 中的索引子集迭代器