任何人都可以建议一种方法来创建一个类的整数键吗?

时间:2017-07-18 08:44:51

标签: c++ algorithm hash

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

我在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对象。

*****根据评论:汽车都不一样,没有相同的汽车********

*****这四个成员是静态的:他们在创建后不会发生变化*****

有人能指出我正确的解决方案吗?

由于

3 个答案:

答案 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,例如