簡體   English   中英

在我的情況下,如何重載 equal 方法以使不同的對象在 unordered_multimap 中具有相同的哈希碼值

[英]How can I overload equal method to make different objects have same hashcode value in unordered_multimap in my case

我寫了一個這樣的地圖:

unordered_multimap<Point, int, StrHash, StrCompare> map

StrHash()是創建哈希碼, StrCompare()是解決哈希碼沖突。 但我想做以下事情:

A 和 B 具有不同的哈希碼值,但 A 等於 B,然后運行StrCompare()方法。 我該怎么做,就像A(220,119)A(220,119)Point B(220,220)有不同的哈希碼一樣。 我可以重載 hashcode equal 方法使A == B嗎? 在我的情況下,我想得到Points ,它們相互比較(abs(ax - bx) + abs(ay - by) < 3) 就像Point(220,220)(220,119)(220,118)(220,220)我的代碼如下:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <math.h>
#include <string>

using std::string;
#include <unordered_map>
using std::unordered_multimap;
using namespace std;
using namespace cv;
class StrHash{
public:
    size_t operator()(const Point a) const {

        return a.x * 1000 + a.y;
    }
};
class StrCompare{
public:
    bool operator()(const Point& a, const Point& b) const {

        if (abs(a.x - b.x) + abs(a.y - b.y) < 3) {
            return true;
        }
        else
            return false;
    }

};

int main()
{
    unordered_multimap<Point, int, StrHash, StrCompare> map;
    map.insert(make_pair(Point(30, 120), 1));
    map.insert(make_pair(Point(220, 120), 2));
    map.insert(make_pair(Point(220, 120), 3));
    map.insert(make_pair(Point(220, 120), 4));
    map.insert(make_pair(Point(220, 119), 5));
    map.insert(make_pair(Point(30, 120), 6));
    unordered_multimap<Point, int, StrCompare>::iterator iter1;
    unordered_multimap<Point, int, StrCompare>::iterator iter2;
    for (iter1 = map.begin(); iter1 != map.end();)//
    {
        int num = map.count((*iter1).first);
        iter2 = map.find((*iter1).first);
        if (num > 2) {
            for (int i = 1; i <= num; i++)
            {
                cout << (*iter2).first << "  " << i << endl;
                iter2++;
            }
            iter1++;
        }
        else {

            iter1++;

        }

    }

}

這不是哈希映射/ unordered_map工作方式。 根據定義,如果散列不相等,則對象不相等。 不僅如此,您的“相等”運算符還允許A(220,119)B(220,220)C(220, 222) ,其中 A == B 和 B == C 但 A != C。我看不到有什么方法可以完成您在這個問題中提出的問題,但是您是否正在嘗試解決真正的問題?

根據您的評論,聽起來您想要std::vector而不是std::unordered_map 然后您只需使用std::find來查找您關心的元素,而不是通過具有無操作哈希的間接方法。

不得不說這是因為如果您的容錯允許它會容易得多:您可以將您的值四舍五入到最接近的 2 或 3 的倍數。


MarkB 的使用vector的建議非常好......只是為了知識分子的興趣列出了一些其他的。


使用unordered_map可以獲得您想要的功能,但不是很干凈:您需要使用地圖的代碼來編排近似相等的邏輯。 首先,相等函數必須檢查實際相等:

struct PointCompare{
    bool operator()(const Point& a, const Point& b) const {
        return a.x == b.x && a.y == b.y;
    }
};

然后,您將需要這樣的支持功能:

template <class Map>
auto approx_find(Map& map, const Point& point) -> decltype(map.begin())
{
    decltype(map.end()) it;
    for (int x_offset = -2; x_offset <= 2, ++x_offset)
        for (int y_offset = -2; y_offset <= 2, ++y_offset)
            if (abs(x_offset) + abs(y_offset) < 3 &&
                (it = map.find({point.x + x_offset, point.y + y_offset})) != map.end())
            return it;
    return map.end();
}

然后,您可以使用返回的迭代器來查看您正在考慮插入的Point是否會重復,以及用於查找、 erase等。

請注意,性能不會很好。 每個approx_find都有效地搜索Point參數,如下所示:

       <------------- X axis -------------->
  ^
  |                   0,-2
  |             -1,-1 0,-1 1,-1
Y axis      -2,0 -1,0 0,0  1,0, 2,0
  |              -1,1 0,1  1,1
  |                   0,2
  v

總而言之,這是 13 次查找 - 或多或少隨機地分散在哈希表的存儲桶周圍,因此不是特別適合緩存 - 而不是通常的 1 次。


一個完全不同的選擇是使用unordered_multimap來跟蹤圖的一般區域中的Point s - 足夠接近它們可能滿足<3鄰近測試。 例如:

std::unordered_multimap<Point, Point> areas;

Point p = { ...whatever... }; 

// keys for nearby points:
Point around[] = { { (p.x - 2) / 3 * 3, (p.y - 2) / 3 * 3 }, 
                   { (p.x + 2) / 3 * 3, (p.y - 2) / 3 * 3 },
                   { (p.x - 2) / 3 * 3, (p.y + 2) / 3 * 3 },
                   { (p.x + 2) / 3 * 3, (p.y + 2) / 3 * 3 } };

對於四個around[]條目中的每一個,在多multimap進行find以查看是否存在精確或近似匹配:這將 13 個表探針減少到只有 4 個。每個多multimap鍵永遠不會映射到超過 2 個條目,因為唯一的非近似沖突是區域對角的兩個Points

暫無
暫無

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

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