代码之家  ›  专栏  ›  技术社区  ›  galactica

如何使自定义类型在无序映射中用作键

  •  -1
  • galactica  · 技术社区  · 6 年前

    我正在尝试获取自定义哈希表来处理自定义类型。 unordered_map constructor error (equal_to templated function)

    我有:

    typedef pair<int, int> tCoord;
    struct hashing_func {
        unsigned long operator()(const tCoord& key) const {
            unsigned long hash = 0;
            int h1 = key.first;
            int h2 = key.second;
            return h1 ^ (h2 << 1);
    
        }
    };
    
    struct key_equal_fn {
        bool operator()(const tCoord& t1, const tCoord& t2) const {
            return t1.first == t2.first && t1.second == t2.second;
        }
    };
    
    unordered_map<tCoord, int, hashing_func, key_equal_fn> coord2cnt;
    unordered_map<tCoord, int, hashing_func, key_equal_fn>::iterator iter;
    iter = coord2cnt.find(coord);
    

    此代码段未编译,并抱怨缺少对find()的函数调用:

    error: no matching member function for call to 'find'
    

    coord2cnt[coord] ,但也有丢失的错误 [] 接线员。

    typedef unordered_map<string, string, hashing_func, key_equal_fn> MapType;
    MapType::size_type n = 5;
    MapType mymap(n, hashing_func(), key_equal_fn());
    

    还想知道为什么这种类型的定义会起作用,即在第一个参数中指定5。这种定义方式似乎在无序映射API中丢失了??

    有人知道这里出了什么问题吗? 谢谢!

    更新:如前所述,string是一个内部类,它有一个内置的hash函数可用。所以我在这里重新表述了这个问题,使用定制的类型。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Archit J    6 年前

    字符串作为键的无序映射在内部处理。不必将字符串的哈希函数定义为键。

    如果要将类或结构作为键传递。然后,您必须为它定义一个哈希函数,以计算冲突最小的键的哈希索引。若要使用.find查找结构或类对象,请在正在使用的结构或类中重载bool operator==。

    例子:

    #include <iostream>
    #include<unordered_map>
    int main() {
      std::unordered_map<std::string, int> myMap;
      myMap.insert({"asd", 1});
      myMap.insert({"qwe", 2});
      std::string input;
      std::cout<<"Enter String: ";
      std::cin>>input;
      std::unordered_map<std::string, int>::iterator it = myMap.find(input);
    
      if(it != myMap.end())
        std::cout<<"Found";
      else
        std::cout<<"Not Found";
    }
    
        2
  •  -1
  •   chaos    6 年前

    与“text2cnt”不匹配

    如果您想以完全专用的模板方式执行此操作,请执行以下操作:

    template <typename T>
    struct key_equal_fn {
        bool operator()(const T& t1, const T& t2) const {
            return t1==t2;
        }
    };
    
    template<>
    struct key_equal_fn<string> {
        bool operator()(const string& t1, const string& t2) const {
            return !(t1.compare(t2));
        }
    };
    
    unordered_map<string, string, hashing_func, key_equal_fn<string> > text2cnt;
    unordered_map<string, string, hashing_func, key_equal_fn<string> >::iterator iter;