Two dimensional unordered_map

人走茶凉 提交于 2019-12-10 21:34:42

问题


typedef boost::unordered_map<int, void*> OneDimentionalNodes;
typedef boost::unordered_map<int, OneDimentionalNodes> TwoDimentionalNodes;

TwoDimentionalNodes nodes;

is this valid?

i don't use any hash functions since keys of the unordered_maps' are single integers. it compiles, but when i iterate it like this, it crashes while trying to access this->hash_function()(k);

for (TwoDimentionalNodes::iterator it= nodes.begin(); it != nodes.end() ; ++it)
{
   for(OneDimentionalNodes::iterator it2 = nodes[it->first].begin(); it2 != nodes[it->first].end() ; ++it2)
    {
   // do stuff
    }
}

i'm also open to other containers with

  • O(1) access
  • O(n) iteration
  • Sparse

回答1:


If you just need to iterator over all elements, and it is not required to loop over a specific dimension, then you could use a simple pair as key for your unordered_map, like this:

typedef std::pair<int,int> Coordinates;
typedef std::unordered_map<Coordinates,void *> TwoDimensionalNodes;

(notice I used STL instead of Boost, unordered_map is now also part of the standard STL).

Getting a specific value is simply writing:

twoDimensionalNodes[std::make_pair(x,y)]

(or use find if you're not sure if that value is in your map).

To iterate, just iterate over the unordered map:

for (auto it=twoDimensionalNodes.begin();it!=twoDimensionalNodes.end();++it)
   {
   std::cout << "x=" << it->first.first;
   std::cout << "y=" << it->first.second;
   std::cout << "value=" << it->second;
   }

To make it a bit more readable, I prefer getting the coordinates first from the iterator, like this:

for (auto it=twoDimensionalNodes.begin();it!=twoDimensionalNodes.end();++it)
   {
   Coordinates &coordinates = it->first;
   std::cout << "x=" << coordinates.first;
   std::cout << "y=" << coordinates.second;
   std::cout << "value=" << it->second;
   }

If you have more than 2 dimensions, use std::tuple, or simply write your own Coordinates class to be used as key for the map.




回答2:


Use std::unordered_map from <unordered_map>. Try to specialize std hash class this way:

namespace std
{
    template<typename T> 
    struct hash<void*>
    {
        std::size_t operator()(void * ptr) const
        {
            return (std::size_t)ptr;
        }
    };
}


来源:https://stackoverflow.com/questions/10244988/two-dimensional-unordered-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!