循环通过结构作为关键的地图。

时间:2015-12-14 15:01:36

标签: c++ struct stdmap

我有一个结构

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;

如果有人可以提供一些关于这是否可以实现的评论(我不想使用增强容器),那将是非常友好的。

3 个答案:

答案 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

只是说,当你不复杂时,它会更好!