C++ 有人能提出一种从类中创建整数键的方法吗?

C++ 有人能提出一种从类中创建整数键的方法吗?,c++,algorithm,hash,C++,Algorithm,Hash,我是计算机科学的新手,我想这和哈希函数有关 我有一门cpp课程: class Car{ public: int fleetId; OwnershipEnum owner; int buildDate; bool hasFourDoors; ... with many other members }; 现在,我的问题是,如何根据我列出的4个成员“科学地”生成一个整数键 我可以想出一个简单的方法,10000*int(fleetId)+1000*in

我是计算机科学的新手,我想这和哈希函数有关

我有一门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)


我认为理想情况下,密钥是连续的,因此我可以将所有汽车对象存储在一个数组中,并使用生成的密钥直接访问汽车对象

*****根据评论:汽车都是不同的,没有完全相同的汽车********

*****这四个成员是静态的:它们在创建后不会更改*****

有人能给我指出正确的解决方法吗


谢谢

您可以使用
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);
}
std::size\u t CarHash(const Car和Car)
{
std::size\u t h1=std::hash{}(car.fleetId);
std::size_t h2=std::hash{}(int(car.owner));
std::size_t h3=std::hash{}(int(car.isGoodCondition));
std::size_t h4=std::hash{}(int(car.isBooked));

return h1^(h2这些成员的组合不足以唯一地识别一辆车:想象两辆车具有相同的车队ID(因为是同一车队的一部分),同一所有者,并且都已预订且状态良好。如果根据这些属性计算,则会产生相同的id。正如@jsheeran所建议的,您可以使用车牌作为唯一标识符

否则,请将id的另一个成员添加到您的car类中,并在car的每个构造函数调用中为全局递增键添加一个静态变量。但是,请注意,这只是一个示例实现,您可能希望使用另一个类来管理键,因为此实现永远不会“释放”键

等级车{
公众:
Car():id(++nextId){}
常量无符号id;
私人:
静态无符号nextId;
};
未签名的汽车::nextId=0U;//使用汽车在cpp中初始化
int main()
{
a车;
b车;
c车;

std::cout假设您想要一个没有冲突的键,并且所有字段都可以接受其范围内的任何值,您必须使用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
struct键{
intfleetid;
所有者;所有者;
焦炉;
钥匙(车_我的车):
fleetId(_myCar.fleetId),
车主(_myCar.owner),

布尔(!!myCar.isGoodCondition&!!myCar.isBooked两个不同的
Car
实例可以共享同一个键吗?通常不能确保所有键都不同,除非每个字段的值范围很小。必须考虑哈希冲突。键的目的是唯一地标识对象。这意味着
isGoodCo条件
isBooked
不适合包含在钥匙中,因为这些值会随着时间的推移而变化。对于一辆汽车,诸如其车牌和登记日期之类的信息应该足以识别它。“理想情况下,钥匙是连续的,因此我可以存储所有汽车对象”这是否意味着将只有一个car数组,并且数组是常量数组?这些字段看起来仍然不唯一。我不确定您是否可以拥有唯一的密钥,而其中至少两个字段对于生产的每辆车都具有互斥值,或者一个值是互斥的(唯一的)给每辆车。比如注册号/底盘号/发动机号等。小问题:你认为只使用对象的地址就足够了吗,因为它们应该是唯一的?
std::hash{}(int(car));
你能解释一下吗?@yassin不,它没有解释(因为它是错误的),我刚刚修复了它,谢谢你指出:)@DanielSanchez这还需要一个类型转换函数,对吗?@yassin,是的,但因为他在他的示例中提供了代码,我按了他已经有了。编辑:实际上我读错了,我又在更新。
  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