使用自定义哈希函数插入到unordered_set中 [英] Inserting into unordered_set with custom hash function
问题描述
我有以下代码,使 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 $ c $
> 第二个问题:
您应该记住,哈希函数应该被限定为
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 theunordered_set<>
class template. The second argument should be the type of your hasher functor, andstd::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
andend
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 typeInterval
, 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 thestd::unordered_set
class template,operator ==
will be used.You currently do not have any overload of
operator ==
for your classInterval
, 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屋!