微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何遍历 C++ 中的向量向量?

如何解决如何遍历 C++ 中的向量向量?

我想知道是否可以通过迭代器访问 std::vector<std::vector<int>> 的元素:我不明白为什么这不会编译:

#include<vector> 
#include<iostream> 

std::vector<std::vector<int>> vec {{1,2},{3,4}} ; 

// to access the single vector 
auto it = vec.begin() ; 

// to access the element of the vector 
auto iit = it.begin() ; 

这是我得到的错误

prova.cpp: In function ‘int main()’:
prova.cpp:10:15: error: ‘class __gnu_cxx::__normal_iterator<std::vector<int>*,std::vector<std::vector<int> > >’ has no member named ‘begin’
   10 | auto iit = it.begin() ;

解决方法

您可以从对内部向量的引用获取到内部元素的迭代器。迭代器不是对元素的引用,但您必须取消引用它。改变这个:

// to access the element of the vector 
auto iit = it.begin() ; 

auto iit = it->begin();

不要把事情复杂化。你像这样迭代一个向量:

std::vector<T> vect;

for (auto it = vect.begin(); it != vect.end(); ++it) {
     auto& element = *it;
     // element is a reference to the element in the vector
}

或使用基于范围的循环:

for (auto& element : vect) {
     // element is a reference to the element in the vector
}

真的没有比这更复杂的了。

当您有一个嵌套向量并且想要迭代内部向量的元素时,您只需要首先获取外部向量的元素,然后获取内部向量的元素:

std::vector<std::vector<T>> vect2;
for (auto& inner_vector : vect2) {
     // inner_vector is reference to element of vect2
     for (auto& element : inner_vector) {
          // element is reference to element of inner vector
     }
}
,
auto iit = it.begin();

无法编译,因为 it 是迭代器,而不是向量。您应该使用重载的 value-of 运算符来获取 it 指向的向量。

auto iit = (*it).begin();

然后你就可以正常使用迭代器了。 您还可以使用基于范围的 for 循环:

for(auto &row : vec) {
    for(auto &col : row) {
        // do things
    }
}
,

迭代器在特别是随机访问迭代器中模拟指针的行为。

例如,如果您有一个类的对象,例如

struct A
{
    int x;
} a = { 10 };

和一个指向对象的指针

A *pa = &a;

然后使用您需要编写的指针访问对象的数据成员,例如

std::cout << pa->x << '\n';

std::cout << ( *pa ).x << '\n';

所以考虑这个声明

auto it = vec.begin();

作为一个指针的声明。

所以使用这个迭代器你可以得到存储向量的迭代器,比如

auto iit1 = it->begin() ;  

auto iit2 = ( ++it )->begin()'

使用这种方法,您可以编写嵌套的 for 循环来输出向量。

这是一个演示程序

#include <iostream>
#include <vector>

int main() 
{
    std::vector<std::vector<int>> vec { { 1,2 },{ 3,4 } };
    
    for ( auto it = vec.cbegin(); it != vec.cend(); ++it )
    {
        for ( auto iit = it->cbegin(); iit != it->cend(); ++iit )
        {
            std::cout << *iit << ' ';
        }
        std::cout << '\n';
    }
    
    std::cout << '\n';
    
    return 0;
}

程序输出为

1 2 
3 4

我使用成员函数 cbegincend 而不是 beginend 来表明向量没有在循环内改变。

要做到这一点,使用基于范围的 for 循环更简单。例如

#include <iostream>
#include <vector>

int main() 
{
    std::vector<std::vector<int>> vec { { 1,4 } };
    
    for (const auto &v : vec )
    {
        for ( const auto &item :v )
        {
            std::cout << item << ' ';
        }
        std::cout << '\n';
    }
    
    std::cout << '\n';
    
    return 0;
}

程序输出与上图相同。

在基于范围的 for 循环中,编译器本身会取消引用迭代器而不是您。

,

如果你真的想使用迭代器,下面的代码就可以了。

#include<vector> 
#include<iostream> 

int main()
{
    std::vector<std::vector<int>> vec {{1,2},{3,4}} ; 
    
    for (auto it = vec.cbegin(); it != vec.cend(); ++it)
    {
        for (auto iit = it->cbegin(); iit != it->cend(); ++iit)
        {
            std::cout << "elem: " << *iit << "\n";
        }
    }
}

否则,请务必使用 ranged for 循环。

#include<vector> 
#include<iostream> 

int main()
{
    std::vector<std::vector<int>> vec {{1,4}} ; 
    for (const auto& inner_vec : vec)
    {
        for (const auto& elem : inner_vec)
        {
            std::cout << "elem: " << elem << '\n';
        }
    }
    
}
,

根据Cplusplus

迭代器是指向某个范围内的某个元素的任何对象 元素(例如数组或容器)

vector <int> v = {0,1,2};
auto it = v.begin();
// it is a iterator pointing to the first element of the vector
// To access the first element,we will use *it

cout << *it; // will output 0
// Notice how * is used to get the value where it points at

就您而言,vec 是向量的向量。其中 vec 的每个元素本身就是一个向量。上面代码片段中定义的 v 的每个元素都是一个 int

std::vector<std::vector<int>> vec {{1,4}} ; 

// it is an iterator pointing to the elements of vec
// Notice that it points to the elements of vec
// Each element of vec is a vector itself
// So it "points" to a vector
auto it = vec.begin() ; 

// to access the element of the vector 
//auto iit = it.begin() ; 

// To access the elements (which are int) of the vector,you need to use: 
auto iit = (*it).begin();

// *it is the value where it points to (which is basically the first vector )

另一种迭代 vec 的方法是使用 for each 循环

for(auto v : vec)
{
     for(int a : v)
     {
         cout<<a;
         // a is an integer
     }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。