如何改进此代码,以便使用迭代器而不是索引访问?
当前的实现并不安全,因为我可能会超出绑定向量a
,当然我可以在调用at
方法之前先检查向量大小,但我很想知道更好的代码,比如使用for_each
或其他现代cpp或lambda表达式?
std::vector<int> a = { 1, 2, 3 };
std::vector<int> b = { 2, 1 };
std::vector<double> result;
for (int i = 0; i < b.size(); i++) {
int current = a.at(i);
int next = a.at(i + 1);
double average = (current + next) / static_cast<double>(b.at(i));
result.push_back(average);
}
答案 0 :(得分:1)
IMO这是做到这一点的最明智的方式,而且它的速度远远不如此*:
assert(a.size() == b.size() + 1);
for (int i = 0; i < b.size(); ++i) {
result.push_back((a[i] + a[i + 1]) / static_cast<double>(b[i]));
}
这是完全安全的,因为断言确保索引有效。
如果您还需要在发布模式下验证矢量长度,只需将assert
切换到某个if
检查。
*(您可以将b.size()
移出循环并预先分配result
但是关于它的内容
答案 1 :(得分:1)
根据迭代器实现算法最像stl,并且会产生高效的代码。
它还具有描述算法而不是容器的优点,因此它具有多种用途。
#include <vector>
#include <cassert>
#include <iostream>
#include <iterator>
template<class Iter1, class Iter2, class OutIter>
void compute_splits(Iter1 first1, Iter1 last1,
Iter2 first2, Iter2 last2,
OutIter dest) {
using t1 = typename std::iterator_traits<Iter1>::value_type;
using t2 = typename std::iterator_traits<Iter2>::value_type;
using tt = std::common_type_t<t1, t2>;
// check preconditions
auto valid = std::distance(first1, last1) == (1 + std::distance(first2, last2));
assert(valid);
while (first2 != last2) {
tt tot = *first1 + *std::next(first1);
tot /= *first2;
*dest = tot;
++first1;
++first2;
++dest;
}
}
int main() {
std::vector<int> a = {1, 2, 3};
std::vector<double> b = {2, 1};
std::vector<double> result;
compute_splits(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(result));
std::copy(result.begin(), result.end(), std::ostream_iterator<double>(std::cout, ", "));
std::cout << std::endl;
}
预期产出:
1.5, 5,