如何在c++向量上跟踪当前和以前的迭代器

How to keep track of current and previous iterator on a c++ vector?

本文关键字:迭代器 跟踪 c++ 向量      更新时间:2023-10-16

我有一个向量容器,我想使用当前迭代器和以前的迭代器对其内容的值进行减法运算,任何帮助都将非常感谢

vector<MyClass>::iterator itPrevious = my_vec.begin();
vector<MyClass>::iterator itCurrent = itPrevious;
if (itCurrent != my_vec.end())
{
    for (++itCurrent;  itCurrent != my_vec.end();  ++itCurrent)
    {
        // do something with itPrevious and itCurrent
        itPrevious = itCurrent;
    }
}

std::vector的迭代器是RandomAccessIterator,因此可以对其执行整数运算。因此,只要从begin() + 1:开始迭代,就不需要单独的"当前"answers"上一个"指针

vector<Foo> myVec = ...;
if(myVec.size() > 1) { 
    for(vector<Foo>::iterator iter = myVec.begin()+1; iter != myVec.end(); iter++) {
        Foo current = *iter;
        Foo previous = *(iter - 1);
        Foo subtraction = current - previous;
        ...
    }
}

当然,如果向量中的元素少于两个,则不能减去当前元素和上一个元素。如果您知道您的输入向量总是至少有两个元素,那么大小检查可能是多余的,但为了安全起见,我将其包含在内。

如果你要求一个向量,你可以使用迭代器算法:

#include <vector>
#include <iostream>
int main() {
    std::vector<int> v{ 1, 2, 3, 4 };
    for ( auto i = v.begin(); i != v.end(); ++i ) {
        if ( i != v.begin() )
            *i = *i - *(i-1);
    }
    for ( auto i : v )
        std::cout << i << std::endl;
}
if(v.size() < 2)
   return;
auto curr = v.begin();
auto next = curr;
++next;
do
{
  whatever(*next - *curr );
  curr = next++;
} while( next != v.end() )

替代方案:

for (auto previous = v.begin(), current = previous + 1, end = v.end();
    previous != end && current != end;
    ++previous, ++current)
{
    std::cout << *current << " - " << *previous << " = " << *current - *previous << std::endl;
}

有三种或多或少优雅的方法来解决您的问题。

定义一个新的函子

并将其用于for_each迭代

template<class T>
struct substractor {
    substractor() : last(nullptr) {}
    void operator()(T& item) const
    {
        if(last != nullptr)
            *last -= item;
        last = &item;
    }
    mutable T* last;
};
...
vector<int> v = {3, 2, 1};
for_each(v.begin(), v.end(), substractor<int>());

定义新算法

中的某种对在位变换

template<typename It, typename Op>
void pair_transform(It begin, It end, Op op){
    while(begin != end)
    {
        It next = std::next(begin);
        if(next == end) break;
        *begin = op(*begin, *next);
        ++begin;
    }
}
...
vector<int> w = {3, 2, 1};
pair_transform(w.begin(), w.end(), std::minus<int>());

保持标准,使用转换

IMHO最好的一个:)简洁、标准,无需其他地方查看即可理解此代码。

vector<int> z = {3, 2, 1};
std::transform(z.begin(), z.end() - 1, z.begin() + 1, z.begin(), 
    std::minus<int>());