如何访问/遍历unordered_multimap中的所有非唯一键?

时间:2013-05-31 07:01:53

标签: c++ iterator hashtable unordered-map

我想访问/遍历unordered_multimap中的所有非唯一键。 哈希表基本上是来自签名<SIG>的映射,其实际上在实践中确实出现多次到标识符<ID>。我想在哈希表中找到那些出现一次的条目。

目前我使用这种方法:

// map <SIG> -> <ID>
typedef unordered_multimap<int, int>    HashTable;
HashTable& ht = ...;
for(HashTable::iterator it = ht.begin(); it != ht.end(); ++it)
{
    size_t n=0;
    std::pair<HashTable::iterator, HashTable::iterator> itpair = ht.equal_range(it->first); 
    for (   ; itpair.first != itpair.second; ++itpair.first) {  
        ++n;
    }
    if( n > 1 ){ // access those items again as the previous iterators are not valid anymore
        std::pair<HashTable::iterator, HashTable::iterator> itpair = ht.equal_range(it->first); 
        for (   ; itpair.first != itpair.second; ++itpair.first) {  
           // do something with those items
        }
    }
}

这肯定是无效的,因为外部循环遍历散列表的所有元素(通过ht.begin()),内部循环测试相应的键是否存在多次。

有更高效或更优雅的方法吗?

注意:我知道使用unordered_map代替unordered_multimap我不会遇到此问题,但由于应用程序要求,我必须能够存储指向不同的多个密钥<SIG>标识符<ID>。另外,unordered_map<SIG, vector<ID> >对我来说不是一个好选择,因为它使用了大约150%的内存,因为我有许多唯一的密钥,vector<ID>为每个项目增加了相当多的开销。

2 个答案:

答案 0 :(得分:2)

使用std::unordered_multimap::count()确定具有特定密钥的元素数量。这为您节省了第一个内循环。

您无法阻止对整个HashTable进行迭代。为此,HashTable必须维护第二个索引,将基数映射到键。这将引入显着的运行时和存储开销,并且仅在少数情况下有用。

您可以使用std::for_each()隐藏外部循环,但我认为这不值得。

答案 1 :(得分:0)

我认为您应该将数据模型更改为:

std::map<int, std::vector<int> > ht;

然后您可以轻松地迭代地图,并检查每个元素包含size()

的项目数量

但在这种情况下,构建数据结构并以线性模式读取它会稍微复杂一些。