boost :: unordered_multimap:有效获取存储桶中的所有元素?

时间:2013-12-30 18:39:02

标签: c++ boost multimap bucket boost-unordered

我可以使用以下代码将所有元素放在一个存储桶中:

typedef boost::unordered_multimap< key, myClass*, MyHash<key> >
                                                HashMMap;
HashMMap::iterator it;
it = hashMMap_.find( someKey);
int bucketIndex = hashMMap_.bucket( someKey);
int bucketSize = hashMMap_.bucket_size( bucketIndex);

qDebug() << "index of bucket with key:" << someKey << " is:"
         << bucketIndex;
qDebug() << "number of elements in bucket with index:" << bucketIndex << " is:"
         << bucketSize;

HashMMap::local_iterator lit;
/* begin of bucket with index bucketIndex */
lit = hashMMap_.begin( bucketIndex);

for ( ; lit != sender_.hashMMap_.end( bucketIndex); ++lit) {
    qDebug() << "(*lit).first:" << (*lit).first << ", (*lit).second:" <<
               (*lit).second << ", (*lit).second->something_:" <<
               (*lit).second->something_;
}

我想将一个local_iterator放到一个桶中的第一个元素并迭代它直到桶结束,所以如果哈希表中给定索引只有一个值(其中index是Hash(key) )我将迭代单个元素并接收桶end(),并且在许多元素的情况下,我将迭代整个桶(所有值具有相等的散列)。如果没有bucketIndexhashMMap_.begin( bucketIndex)hashMMap_.end( bucketIndex)

,这是否可行?

所以基本上我想得到一个像这样的local_iterator:

HashMMap::local_iterator lit = hashMMap_.find_bucket_if_present( someKey);

其他问题是:如果find()在调用int bucketIndex = hashMMap_.bucket( someKey)之前返回元素的迭代器,我是否必须先测试?这是我的想法,因为来自boost网站的bucket()函数的解释是:

  

返回:包含元素的存储桶的索引   关键k。

                                 ^^^

我认为这意味着我首先要在多图中find(key)知道密钥是否存在,因为对bucket(key)的调用将返回一个索引,该索引不是散列而是散列模数({ {1}})在存在密钥的哈希表中,如果存在密钥。因此,由于使用bucket_from_hash完成的模数,​​如果未插入密钥,我将迭代虚拟存储桶,在当前情况下,它将对我来说最重要的是:也可能存在不同的哈希值因为bucket_count可能小于我的哈希值(我使用32位密钥的16位bucket_count作为多地图构造函数中提供的哈希函数)。这是对的吗?

1 个答案:

答案 0 :(得分:3)

我会开始使用范围,如下:

template<typename BoostUnorderedMap, typename Key>
boost::iterator_range< typename BoostUnorderedMap::local_iterator > get_bucket_range( BoostUnorderedMap& myMap, Key const& k ) {
  int bucketIndex = myMap.bucket( k );
  return boost::iterator_range< typename BoostUnorderedMap::local_iterator >(
    myMap.begin(bucketIndex),
    myMap.end(bucketIndex)
  }
}
template<typename BoostUnorderedMap, typename Key>
boost::iterator_range< typename BoostUnorderedMap::local_const_iterator > get_bucket_range( BoostUnorderedMap const& myMap, Key const& k ) {
  int bucketIndex = myMap.bucket( k );
  return boost::iterator_range< typename BoostUnorderedMap::local_const_iterator >(
    myMap.begin(bucketIndex),
    myMap.end(bucketIndex)
  }
}

然后,至少在C ++ 11中,您可以执行以下操作:

for (auto && entry : get_bucket_range( some_map, "bob" ) )

它会遍历"bob"存储桶中的所有内容。

虽然这确实使用了bucketIndex,但它会隐藏最终消费者的这些详细信息,而只是为您提供boost::range