如何访问/迭代unordered_multimap中的所有非唯一键

How to access/iterate over all non-unique keys in an unordered_multimap?

本文关键字:multimap 一键 唯一 unordered 何访问 访问 迭代      更新时间:2023-10-16

我想访问/迭代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>为每个项增加了相当多的开销。

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

你不能阻止整个HashTable的迭代。为此,HashTable必须维护第二个索引,将基数映射到键。这将引入大量的运行时和存储开销,并且仅在少数情况下有用。

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

我认为你应该把你的数据模型改成:

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

然后您可以很容易地遍历map,并使用size()

检查每个元素包含多少项

但是在这种情况下,建立一个数据结构并以线性模式读取它就有点复杂了