[英]Iterating over 2-dimensional STL vector c++
I'm currently trying to print out a history of movements for players in a game I am working on. 我正在尝试打印我正在制作的游戏中玩家的动作历史。 At the end of each round every player has moved some amount in the positive or negative direction and this gets recorded as an int in the movement vector.
在每轮结束时,每个玩家都在正方向或负方向上移动了一些数量,并将其记录为运动矢量中的int。 Eventually I'm wanting to plot the directions moved vs time for each player but I'm having trouble extracting the data out of the 2d vector.
最终我想要为每个玩家绘制移动方向与时间的关系,但是我无法从2d向量中提取数据。
So the first thing I tried was to just iterate and print all the elements, however this doesn't compile: 所以我尝试的第一件事就是迭代并打印所有元素,但是这不能编译:
void output_movement(const std::vector< std::vector<int> > & movement){
std::vector< std::vector<int> >::iterator row;
std::vector<int>::iterator col;
for (row = movement.begin(); row != movement.end(); ++row) {
for (col = row->begin(); col != row->end(); ++col) {
std::cout << **col;
}
}
}
The compiler gives this error message which I don't really understand: 编译器提供此错误消息,我不太明白:
hg_competition.cpp:45: error: no match for ‘operator=’ in ‘row = ((const std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >*)money_movement)->std::vector<_Tp, _Alloc>::begin [with _Tp = std::vector<int, std::allocator<int> >, _Alloc = std::allocator<std::vector<int, std::allocator<int> > >]()’
/usr/include/c++/4.4/bits/stl_iterator.h:669: note: candidates are: __gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >& __gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >::operator=(const __gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >&)
Any help is greatly appreciated! 任何帮助是极大的赞赏!
You need to use a const_iterator
if the vector
is a const reference. 如果
vector
是const引用,则需要使用const_iterator
。 Also, to output col
you only need to dereference it once. 此外,要输出
col
您只需要取消引用一次。
void output_movement(const std::vector< std::vector<int> > & movement){
std::vector< std::vector<int> >::const_iterator row;
std::vector<int>::const_iterator col;
for (row = movement.begin(); row != movement.end(); ++row) {
for (col = row->begin(); col != row->end(); ++col) {
std::cout << *col;
}
}
}
Edit: using typedefs will make your code more readable 编辑:使用typedef将使您的代码更具可读性
typedef std::vector<int> Vector;
typedef std::vector<Vector> DoubleVector;
void output_movement(
const DoubleVector& movement
)
{
for (DoubleVector::const_iterator row = movement.begin(); row != movement.end(); ++row) {
for (Vector::const_iterator col = row->begin(); col != row->end(); ++col) {
std::cout << *col;
}
std::cout << std::endl;
}
}
The 2D vector
is declared const
, so you need to use const_iterator
instead of iterator
. 2D
vector
声明为const
,因此您需要使用const_iterator
而不是iterator
。
You also shouldn't doubly dereference col
. 你也不应该加倍取消引用
col
。 It is an iterator, so you only need to dereference once. 它是一个迭代器,所以你只需要解除引用一次。
void output_movement(const std::vector< std::vector<int> > & movement){
std::vector< std::vector<int> >::const_iterator row;
std::vector<int>::const_iterator col;
for (row = movement.begin(); row != movement.end(); ++row) {
for (col = row->begin(); col != row->end(); ++col) {
std::cout << *col;
}
}
}
const
objects return const_iterators
, so simply replace iterator
by const_iterator
everywhere. const
对象返回const_iterators
,因此只需用const_iterator
替换iterator
。 This also prevents unwanted modifications of the vectors. 这也可以防止不需要的载体修饰。
This is the combination of Sam's and Mathieu's suggestions: 这是Sam和Mathieu的建议的结合:
#include <ostream>
#include <vector>
typedef std::vector<int> Vector;
typedef std::vector<Vector> DoubleVector;
template<typename Char, typename Traits>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& stream,
const DoubleVector& movement) {
for (DoubleVector::const_iterator row = movement.begin(); row != movement.end(); ++row) {
for (Vector::const_iterator col = row->begin(); col != row->end(); ++col) {
stream << *col;
}
}
return stream;
}
John, you suggested using lambdas, but if C++11 is available, I'd prefer 约翰,你建议使用lambdas,但如果C ++ 11可用,我更喜欢
for (auto& row : movement) {
for (auto& elem : row) {
std::cout << elem;
}
}
Omg, anything is better than that mess of for
loops. 妈呀, 什么是比那些乱七八糟更好
for
循环。 Here some alternatives. 这里有一些选择。 Choose whichever you like.
选择你喜欢的任何一个。
typedef vector<int> VI;
typedef vector<VI> VVI;
namespace std {
ostream& operator<<(ostream& o, const VI& v) {
copy (v.begin(), v.end(), ostream_iterator<int>(cout));
return o;
}
}
void output_movement (const VVI& m) {
copy (m.begin (), m.end (), ostream_iterator<const VI&>(cout));
}
or, 要么,
void output_movement (const VVI & m) {
for_each (m.begin(), m.end(), [](const VI& v){
for_each (v.begin(), v.end(), [](int i){ cout << i; });
});
}
or, my personal preference (boost/foreach.hpp), 或者,我个人的偏好(boost / foreach.hpp),
void output_movement (const VVI & m) {
foreach (const VI& v, m)
foreach (int i, v)
cout << i;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.