簡體   English   中英

使用unordered_multimap

[英]Playing with unordered_multimap

所以,伙計們,我正在玩std::unordered multimap只是為了好玩。 我想存儲(在這個例子中) unsigned short s,帶有自定義哈希並且相等。

有趣的是什么? 如果它們是偶數或奇數,則兩個項目相等。

所以,據我所知,我不能使用std::unordered_map ,即使實際值不同:自定義謂詞另有說法。 (如果我錯了,請糾正我,顯然!)

所以回顧一下:我存儲了不同的整數,因此存儲了不同的 哈希值 ,但它們在謂詞下的值可能是相同的

#include <iostream>
#include <unordered_map>

class tt
{
public:

    tt(const unsigned short v = 0) : i(v) { };

    unsigned short i;
};

class tt_hash
{
public:
    size_t operator()(const tt &v) const
    {
        auto f = std::hash<unsigned short>();
        return f(v.i);
    };
};

class tt_equal
{
public:
    bool operator()(const tt &u, const tt &v) const
    {
        return (u.i % 2) == (v.i % 2);
    };
};

typedef std::unordered_multimap<tt, bool, tt_hash, tt_equal> mymap;

// Print all values that match a criteria
void f(const mymap &m, unsigned short c)
{
    auto range = m.equal_range(c);

    auto target = range.first;

    if (target == m.end())
    {
        std::cout << "not found : " << (int) c << std::endl;
    }
    else
    {
        for (auto i = target; i != range.second; i++)
            std::cout << "there is  : " << (int) i->first.i << " : " << i->second << std::endl;
    }

}

int main(int argc, const char * argv[])
{    
    mymap m;

    m.emplace(std::make_pair(tt(3), false));
    m.emplace(std::make_pair(tt(10), true));
    m.emplace(std::make_pair(tt(4), true));
    m.emplace(std::make_pair(tt(23), false));

    std::cout << "size " << m.size() << std::endl;
    std::cout << "buck " << m.bucket_count() << std::endl;

    int c = 0;

    for (auto i = m.begin(); i != m.end(); i++)
        std::cout << "# " << c++ << " : " << (int) i->first.i << " : " << i->second << std::endl;

    f(m, 3);

    return 0;
}

所以,當我執行上面的代碼時,我找到了正確的值,3,10,4,23(當然不是按此順序)。

出乎意料的是,當打印所有匹配3調用f()的值時,我得到兩個答案,3和23; 但是當我要求1000時,我希望打印所有偶數,但我錯了:

size 4
buck 5
# 0 : 4 : 1
# 1 : 10 : 1
# 2 : 3 : 0
# 3 : 23 : 0
there is  : 10 : 1

我在這里錯過了什么嗎? (答案顯然是肯定的)

你正在做的是未定義的行為:相等的元素應具有相等的哈希值。 根據標准(強調我的)

23.2.5無序關聯容器[unord.req]

5如果容器的鍵等式謂詞在傳遞這些值時返回true,則認為Key類型的兩個值k1和k2是等效的。 如果k1和k2是等價的,則容器的散列函數應為兩者返回相同的值

由於您使用模2定義了等價,因此您還需要在傳遞的整數的模2上使用散列函數。 這也意味着只要有2個以上的元素,就需要std::unordered_multimap

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM