循环遍历以结构为键的地图。
Looping through a map with structure as a key.
我有一个结构
struct key
{
int x;
int y;
int z;
};
假设 x、y、z 可以取 1 到 10 之间的值。
我也有地图
std::map<key,double> myMap;
我用不同的键值填充。
有没有一种方法可以遍历 z=5 的所有键值。即(以伪代码的形式)
loop over myMap
double v += myMap.find({x=anything,y=anything,z=5})->second;
如果有人可以提供一些关于这是否可以实现的评论(我不想使用 boost 容器),那就太好了。
标准关联容器使用一维排序,即它们只知道一个键是小于、等于还是大于另一个。所以这是不可能有效的。您可以使用 std::find_if()
.
在线性时间内实现此类过滤
保持 O(log n)
查找时间,但是可以创建多个地图,使用不同的索引方式;例如一个以 X 为键,一个以 Y 为键,一个以 Z 为键。如果值是大对象,您可以使用指针来避免不必要地复制它们。当然,这一切都可以隐藏在封装 class 后面,它向外部提供基于轴的排序。
另一种适用于小空间(例如从 1 到 10 的 x、y、z)的方法是不使用 std::map
,而是使用 3D array/matrix。这可以使用 1D std::vector
来实现,方法是将索引从 3 维映射到 1.
如果您首先使用 z 对 key
结构进行排序,您可以这样做:
bool operator<( const key &k1, const key &k2 )
{
return std::make_tuple( k1.z, k1.x, k1.y ) < std::make_tuple( k2.z, k2.x, k2.y ); // z must be first
}
auto min = std::numeric_limits<int>::min();
auto end = map.lower_bound( key{ min, min, 6 } );
for( auto it = map.lower_bound( key{ min, min, 5 } ); it != end; ++it ) {
...
}
但是如果您还需要对 x 或 y 进行迭代,则必须使用指向结构的指针为每个坐标创建单独的多图或使用 boost::multiindex
.
#define ARRAY_SIZE 2500 // 2500 is the size of the array
为什么不像
那样创建一个数组数组
double map[2][ARRAY_SIZE];
// map[0][x] - the key of Xth value in the array (example - 10th/1st/2nd ...)
// map[1][x] - the value of Xth value in the array
就是说,不复杂就好!
我有一个结构
struct key
{
int x;
int y;
int z;
};
假设 x、y、z 可以取 1 到 10 之间的值。
我也有地图
std::map<key,double> myMap;
我用不同的键值填充。
有没有一种方法可以遍历 z=5 的所有键值。即(以伪代码的形式)
loop over myMap
double v += myMap.find({x=anything,y=anything,z=5})->second;
如果有人可以提供一些关于这是否可以实现的评论(我不想使用 boost 容器),那就太好了。
标准关联容器使用一维排序,即它们只知道一个键是小于、等于还是大于另一个。所以这是不可能有效的。您可以使用 std::find_if()
.
保持 O(log n)
查找时间,但是可以创建多个地图,使用不同的索引方式;例如一个以 X 为键,一个以 Y 为键,一个以 Z 为键。如果值是大对象,您可以使用指针来避免不必要地复制它们。当然,这一切都可以隐藏在封装 class 后面,它向外部提供基于轴的排序。
另一种适用于小空间(例如从 1 到 10 的 x、y、z)的方法是不使用 std::map
,而是使用 3D array/matrix。这可以使用 1D std::vector
来实现,方法是将索引从 3 维映射到 1.
如果您首先使用 z 对 key
结构进行排序,您可以这样做:
bool operator<( const key &k1, const key &k2 )
{
return std::make_tuple( k1.z, k1.x, k1.y ) < std::make_tuple( k2.z, k2.x, k2.y ); // z must be first
}
auto min = std::numeric_limits<int>::min();
auto end = map.lower_bound( key{ min, min, 6 } );
for( auto it = map.lower_bound( key{ min, min, 5 } ); it != end; ++it ) {
...
}
但是如果您还需要对 x 或 y 进行迭代,则必须使用指向结构的指针为每个坐标创建单独的多图或使用 boost::multiindex
.
#define ARRAY_SIZE 2500 // 2500 is the size of the array
为什么不像
那样创建一个数组数组double map[2][ARRAY_SIZE];
// map[0][x] - the key of Xth value in the array (example - 10th/1st/2nd ...)
// map[1][x] - the value of Xth value in the array
就是说,不复杂就好!