如何使用交替索引访问2个cpp向量?

时间:2017-03-25 13:12:38

标签: c++

如何改进此代码,以便使用迭代器而不是索引访问?

当前的实现并不安全,因为我可能会超出绑定向量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);
} 

2 个答案:

答案 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,