0

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

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 到存储桶中的第一个元素并迭代它直到存储桶结束,所以如果哈希表中的给定索引只有一个值(其中索引是Hash(key)),我将只迭代一个元素并接收桶 end(),如果有很多元素,我将迭代整个桶(所有值都具有相同的哈希值)。如果没有bucketIndex,hashMMap_.begin( bucketIndex)和, 这可能hashMMap_.end( bucketIndex)吗?

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

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

另一个问题是:在调用之前是否必须先测试是否find()将迭代器返回到元素int bucketIndex = hashMMap_.bucket( someKey)?这就是我的想法,因为bucket()boost 网站对功能的解释是:

返回:存储桶的索引,其中包含键为 k 的元素。

                                 ^^^

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

4

1 回答 1

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

于 2013-12-30T19:12:48.710 回答