我有一个结构
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;
如果有人可以提供一些关于这是否可以实现的评论(我不想使用增强容器),那将是非常友好的。
答案 0 :(得分:5)
标准关联容器使用一维排序,即它们只知道一个键是否小于,等于或大于另一个键。所以这不是有效的。您可以使用std::find_if()
在线性时间内完成此类过滤。
维持O(log n)
查询时间,但可以使用不同的索引方法创建多个地图;例如一个用X,一个用Y,一个用Z作为关键。如果值是大对象,则可以使用指针不必不必要地复制它们。当然,这都可以隐藏在封装类的后面,它为外部提供基于轴的排序。
对于小空间(例如x,y,z从1到10)合理的另一种方法是不使用std::map
而是使用3D数组/矩阵。这可以使用1D std::vector
,通过将索引从3维映射到1来实现。
答案 1 :(得分:5)
如果先使用z对key
struct进行排序,可以这样做:
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
。
答案 2 :(得分:0)
#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
只是说,当你不复杂时,它会更好!