使用自定义哈希函数插入到unordered_set中 [英] Inserting into unordered_set with custom hash function

查看:1313
本文介绍了使用自定义哈希函数插入到unordered_set中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码,使 unordered_set< Interval> 。这会编译得很好。

  struct Interval {
unsigned int begin;
unsigned int end;
bool updated; // true if concat。最初为false
int patternIndex; //模式索引。对单个模式有效
int proteinIndex; //蛋白质指数。用于检索模式
};

struct Hash {
size_t operator()(const Interval& interval);
};


size_t Hash :: operator()(const Interval& interval){
string temp = to_string(interval.begin)+ to_string(interval.end)+ to_string interval.proteinIndex);
return hash< string>()(temp);
}

unordered_set< Interval,string,Hash>测试;但是,当我尝试使用以下代码插入时,我无法编译:


b

  for(list< Interval> :: iterator i = concat.begin(); i!= concat.end(); ++ i){
test.insert((* i));
}

此外,我无法确定错误消息有什么问题。



以下是示例:

 注:候选人是:
注意:size_t Hash :: operator()(const Interval&)
note:candidate expects 1 argument,2 provided

我以为我只提供了一个参数...



有人看到我的插入代码有问题吗?请帮助,如果可以 - 我一直在寻找一个解决方案很久了。



编辑:



以下是新的实例化代码: unordered_set< Interval,Hash> test;
但是,我仍然收到一些错误消息。例如:

 注意:候选人是:
注意:size_t Hash :: operator()(const Interval&)< ;近匹配>
注意:隐式'this'参数从'const Hash *'到'Hash *'的未知转换


解决方案

第一个问题:



作为您的实例化 unordered_set<> 类模板的第二个模板参数。 第二个参数应为您的哈希函子的类型, std :: string 不是可调用对象。



也许是要写:

  unordered_set< Interval,/ * string * / Hash>测试; 
// ^^^^^^^^^^^^
//为什么这样?

此外,我建议使用除 begin

> 第二个问题:



您应该记住,哈希函数应该被限定为 const ,所以你的函子应该是:

  struct Hash {
size_t operator()(const Interval& interval)const {
// ^^^^^
//不要忘记这个!
string temp = to_string(interval.b)+
to_string(interval.e)+
to_string(interval.proteinIndex);
return(temp.length());
}
};

第三个问题



最后,如果您希望 std :: unordered_set 能够处理类型 Interval 的对象,您需要定义与您的散列函数一致的等式运算符。默认情况下,如果没有指定任何类型参数作为 std :: unordered_set 类模板的第三个参数, operator == 将被使用。



您目前没有任何重载 operator == code> Interval ,所以你应该提供一个。例如:

  inline bool operator ==(Interval const& lhs,Interval const& rhs)
{
return(lhs.b == rhs.b)&&
(lhs.e == rhs.e)&&&
(lhs.proteinIndex == rhs.proteinIndex);
}

结论



进行所有上述修改后,您可以在此实例中查看您的代码编译。


I have the following code to make an unordered_set<Interval>. This compiles fine.

struct Interval {
  unsigned int begin;
  unsigned int end;
  bool updated;   //true if concat.  initially false
  int patternIndex;  //pattern index. valid for single pattern
  int proteinIndex;   //protein index.  for retrieving the pattern
};

struct Hash {
  size_t operator()(const Interval &interval);
};


size_t Hash::operator()(const Interval &interval){
  string temp = to_string(interval.begin) + to_string(interval.end) + to_string(interval.proteinIndex);
  return hash<string>()(temp);
}

unordered_set<Interval, string, Hash> test;

However, I cannot compile when I try to insert using this code:

  for(list<Interval>::iterator i = concat.begin(); i != concat.end(); ++i){
    test.insert((*i));
  }

Moreover, I cannot determine what the problem is from the error messages.

Here is a sample:

note: candidate is:
note: size_t Hash::operator()(const Interval&)
note:   candidate expects 1 argument, 2 provided  

I thought I only provided 1 argument...

Does anyone see a problem with my insertion code? Please help, if you can - I've been looking for a solution for quite a while now.

EDIT:

Here's the new instantiation code: unordered_set<Interval, Hash> test; However, I'm still receiving a slew of error messages. Ex:

note: candidate is:
note: size_t Hash::operator()(const Interval&) <near match>
note:   no known conversion for implicit ‘this’ parameter from ‘const Hash*’ to ‘Hash*’

解决方案

First problem:

You are passing string as the second template argument for your instantiation of the unordered_set<> class template. The second argument should be the type of your hasher functor, and std::string is not a callable object.

Perhaps meant to write:

unordered_set<Interval, /* string */ Hash> test;
//                      ^^^^^^^^^^^^
//                      Why this?

Also, I would suggest using names other than begin and end for your (member) variables, since those are names of algorithms of the C++ Standard Library.

Second problem:

You should keep in mind, that the hasher function should be qualified as const, so your functor should be:

struct Hash {
   size_t operator() (const Interval &interval) const {
   //                                           ^^^^^
   //                                           Don't forget this!
     string temp = to_string(interval.b) + 
                   to_string(interval.e) + 
                   to_string(interval.proteinIndex);
     return (temp.length());
   }
};

Third problem:

Finally, if you want std::unordered_set to be able to work with objects of type Interval, you need to define an equality operator consistent with your hash function. By default, if you do not specify any type argument as the third parameter of the std::unordered_set class template, operator == will be used.

You currently do not have any overload of operator == for your class Interval, so you should provide one. For example:

inline bool operator == (Interval const& lhs, Interval const& rhs)
{
    return (lhs.b == rhs.b) && 
           (lhs.e == rhs.e) && 
           (lhs.proteinIndex == rhs.proteinIndex); 
}

Conclusion:

After all the above modifications, you can see your code compiling in this live example.

这篇关于使用自定义哈希函数插入到unordered_set中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆