我是计算机科学的新手,我想这与哈希函数有关。
我在cpp中有一个课程:
class Car{
public:
int fleetId;
OwnershipEnum owner;
int buildDate;
bool hasFourDoors;
... with many other members
};
现在,我的问题是,如何科学地'根据我列出的4个成员生成一个整数键?
我可以想到一个简单的方法,10000*int(fleetId) + 1000 * int(owner) + 100×int(buildDate) + int(hasFourDoors)
我认为理想情况下键是连续的,所以我可以将所有Car对象存储在一个数组中,并使用这个生成的键直接访问car对象。
*****根据评论:汽车都不一样,没有相同的汽车********
*****这四个成员是静态的:他们在创建后不会发生变化*****
有人能指出我正确的解决方案吗?
由于
答案 0 :(得分:3)
您可以使用std::hash
构建一个获取它的方法:
这只是一个简单的例子。
std::size_t CarHash(const Car& car)
{
std::size_t h1 = std::hash<int>{}(car.fleetId);
std::size_t h2 = std::hash<int>{}(int(car.owner));
std::size_t h3 = std::hash<int>{}(int(car.isGoodCondition));
std::size_t h4 = std::hash<int>{}(int(car.isBooked));
return h1^(h2 << 1)^(h3 << 2)^(h4 << 3);
}
答案 1 :(得分:3)
这些成员的组合不足以唯一识别汽车:想象一下两辆车具有相同的车队(由于是同一车队的一部分),同一车主,两者都被预订并且状况良好。如果您根据这些属性计算它,则会产生相同的ID。根据@jsheeran的建议,您可以将牌照用作唯一标识符。
否则,将id的另一个成员添加到您的汽车类中,并在汽车的每个构造函数调用中为全局增加键设置一个静态变量。但是,请注意,这只是一个示例实现,您可能希望有另一个类来管理密钥,因为此实现永远不会“释放”密钥。
class Car{
public:
Car() : id(++nextId) {}
const unsigned id;
private:
static unsigned nextId;
};
unsigned Car::nextId = 0U; // initialize in your cpp using the cars
int main()
{
Car a;
Car b;
Car c;
std::cout << a.id << b.id << c.id; // will print 012
}
另一个建议是使用GUID。根据您的平台或使用的库,您可以在此处找到解决方案,例如:https://msdn.microsoft.com/en-us/library/ms688568(VS.85).aspx
答案 2 :(得分:0)
假设您想要一个没有冲突的密钥,并且所有字段都可以在其范围内取任何值,您必须使用sizeof(int)+ sizeof(OwnershipEnum)+ 2位密钥来防止所有冲突,或66位。它可以被认为是可接受的并且计算如下:
struct key {
int fleetId;
OwnershipEnum owner;
char bools;
key(Car _myCar) :
fleetId(_myCar.fleetId),
owner(_myCar.owner),
bools(!!_myCar.isGoodCondition & !!_myCar.isBooked << 1 )
{}
bool operator ==(key other) { return fleetId == other.fleetId && owner == other.owner && bools == other.bools; }
};
然后像这样测试:
Car first{1, (OwnershipEnum)2, false, true};
Car second{1, (OwnershipEnum)2, false, true};
Car third{8, (OwnershipEnum)1, true, true};
key k1{first}, k2{second}, k3{third};
std::cout << (k1 == k2) << "\n"; //true
std::cout << (k2 == k3) << "\n"; //false
std::cout << (k3 == k1) << "\n"; //false
完整的示例程序:http://cpp.sh/2vv2a
这显然是一个错误的假设,但是你可以尝试减小密钥大小,如果你可以为fleetId设置所有可能值16位或缩短OwnershipEnum,例如