如何在 C++ 中遍历向量的向量?
How to iterate through a vector of vector in 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() ;
auto iit = it.begin();
无法编译,因为 it
是迭代器,而不是向量。您应该使用重载的 value-of 运算符来获取 it
.
指向的向量
auto iit = (*it).begin();
然后您就可以正常使用迭代器了。
您还可以使用基于范围的 for 循环:
for(auto &row : vec) {
for(auto &col : row) {
// do things
}
}
如果你真的想使用迭代器,下面的代码就可以完成这项工作。
#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";
}
}
}
否则,一定要使用范围循环。
#include<vector>
#include<iostream>
int main()
{
std::vector<std::vector<int>> vec {{1,2},{3,4}} ;
for (const auto& inner_vec : vec)
{
for (const auto& elem : inner_vec)
{
std::cout << "elem: " << elem << '\n';
}
}
}
您可以从对内部向量的引用中获取到内部元素的迭代器。迭代器不是对元素的引用,但您必须取消引用它。改变这个:
// 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
}
}
迭代器,特别是随机访问迭代器模拟指针的行为。
例如,如果您有一个 class 的对象,例如:
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
我使用了成员函数 cbegin
和 cend
而不是 begin
和 end
来表明向量在循环中没有被改变。
要做到这一点,使用基于范围的 for 循环会更简单。例如:
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<int>> vec { { 1, 2 }, { 3, 4 } };
for (const auto &v : vec )
{
for ( const auto &item :v )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
程序输出同上图
在基于范围的 for 循环中,编译器本身会取消对迭代器的引用,而不是您。
An iterator is any object that, pointing to some element in a range of
elements (such as an array or a container)
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,2},{3,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(auto v : vec)
{
for(int a : v)
{
cout<<a;
// a is an integer
}
}
我想知道是否可以通过迭代器访问 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() ;
auto iit = it.begin();
无法编译,因为 it
是迭代器,而不是向量。您应该使用重载的 value-of 运算符来获取 it
.
auto iit = (*it).begin();
然后您就可以正常使用迭代器了。 您还可以使用基于范围的 for 循环:
for(auto &row : vec) {
for(auto &col : row) {
// do things
}
}
如果你真的想使用迭代器,下面的代码就可以完成这项工作。
#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";
}
}
}
否则,一定要使用范围循环。
#include<vector>
#include<iostream>
int main()
{
std::vector<std::vector<int>> vec {{1,2},{3,4}} ;
for (const auto& inner_vec : vec)
{
for (const auto& elem : inner_vec)
{
std::cout << "elem: " << elem << '\n';
}
}
}
您可以从对内部向量的引用中获取到内部元素的迭代器。迭代器不是对元素的引用,但您必须取消引用它。改变这个:
// 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
}
}
迭代器,特别是随机访问迭代器模拟指针的行为。
例如,如果您有一个 class 的对象,例如:
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
我使用了成员函数 cbegin
和 cend
而不是 begin
和 end
来表明向量在循环中没有被改变。
要做到这一点,使用基于范围的 for 循环会更简单。例如:
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<int>> vec { { 1, 2 }, { 3, 4 } };
for (const auto &v : vec )
{
for ( const auto &item :v )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
程序输出同上图
在基于范围的 for 循环中,编译器本身会取消对迭代器的引用,而不是您。
An iterator is any object that, pointing to some element in a range of elements (such as an array or a container)
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,2},{3,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(auto v : vec)
{
for(int a : v)
{
cout<<a;
// a is an integer
}
}