day*_*yup 8 c++ hash-function unordered-set
如何在一个类中存储类的对象unordered_set?我的程序需要经常检查对象是否存在,如果存在unordered_set,则对该对象进行一些更新.
我已经在线查看了如何使用unordered_set,但遗憾的是大多数教程都是关于使用它int或string类型.但是我如何在课堂上使用它呢?我怎样才能定义一个哈希函数来使node_id下面的例子成为关键的unordered_set?
#include <iostream>
#include <unordered_set>
using namespace std;
// How can I define a hash function that makes 'node' use 'node_id' as key?
struct node
{
string node_id;
double value;
node(string id, double val) : node_id(id), value(val) {}
};
int main()
{
unordered_set<node> set;
set.insert(node("1001", 100));
if(set.find("1001") != set.end()) cout << "1001 found" << endl;
}
Run Code Online (Sandbox Code Playgroud)
cda*_*hms 26
由于这是 Stack Overflow 上 Google 的最高结果,因此C++ unordered_set of objects我将发布一个简单但完全说明性的复制/粘贴可运行示例:
// UnorderedSetOfObjects.cpp
#include <iostream>
#include <vector>
#include <unordered_set>
struct Point
{
int x;
int y;
Point() { }
Point(int x, int y)
{
this->x = x;
this->y = y;
}
bool operator==(const Point& otherPoint) const
{
if (this->x == otherPoint.x && this->y == otherPoint.y) return true;
else return false;
}
struct HashFunction
{
size_t operator()(const Point& point) const
{
size_t xHash = std::hash<int>()(point.x);
size_t yHash = std::hash<int>()(point.y) << 1;
return xHash ^ yHash;
}
};
};
int main(void)
{
std::unordered_set<Point, Point::HashFunction> points;
points.insert(Point(1, 1));
points.insert(Point(2, 2));
points.insert(Point(1, 1)); // notice this is a duplicate with the 1st point so it won't change the set
std::cout << "points: " << "\n";
for (auto& point : points)
{
std::cout << "(" << point.x << ", " << point.y << ")" << "\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以尝试使用以下哈希函数对象(它非常基本,因此您可能希望改进它以避免太多冲突).
struct node_hash {
std::size_t operator()(const node& _node) const {
return std::hash<std::string>()(_node.node_id);
}
}
// ...
std::unordered_set<node, node_hash> node_set;
Run Code Online (Sandbox Code Playgroud)
但是,正如其中一条评论指出的那样,你可能最好在std::unordered_map<std::string, double>这里使用.
我同意sjrowlinson 的观点,对于您的特定用例,std::unordered_map<std::string, double>可能是更好的选择。unordered_set但是,如果由于某种原因您想坚持使用 an ,那么您也可以使用lambda 表达式而不是定义哈希函数。但您还必须提供比较函数 ( equal) 才能使您的代码正常工作。如果您希望两个node实例具有相同的值node_id,那么您可以使用以下代码:
auto hash = [](const node& n){ return std::hash<std::string>()(n.node_id); };
auto equal = [](const node& n1, const node& n2){ return n1.node_id == n2.node_id; };
std::unordered_set<node, decltype(hash), decltype(equal)> set(8, hash, equal);
Run Code Online (Sandbox Code Playgroud)
但是,如果您想使用std::unordered_set::find(),那么您不能简单地"1001"向该函数提供一个字符串(例如 ),因为它需要一个node对象作为参数。不过,下面的代码(创建一个临时对象)可以解决这个问题:
set.insert(node("1001", 100));
if (set.find(node("1001", 0)) != set.end())
std::cout << "1001 found" << std::endl;
Run Code Online (Sandbox Code Playgroud)
请注意,尽管插入的值与函数给定的值不同(分别为 100 和 0),但输出1001 found仍被打印。这是因为比较函数仅在检查相等性时考虑。valuenodevaluenodefind()equalnode_id
| 归档时间: |
|
| 查看次数: |
5418 次 |
| 最近记录: |