一般来说,建立一个将任意长度的字符串映射到固定域的函数是不可能的。这违反了pigeonhole principle。
提出以下建议我看来相当令人费解,但由于缺乏更大范围内的,您的问题,在这里不用...
假设您开发,通过它来运行所有名称的类,所以
class compressor {
explicit compressor(std::size_t seed);
std::string operator()(const std::string &name) const;
}
它有两个成员:一个ctor接受一个种子,一个operator()
接受一个名称字符串并返回一个8个字符的关键字符串。在你的代码中,用一些固定的,任意的种子初始化这个对象。
在内部,类对象应该包含一个unordered_map
映射,对于应用了它的每个不同名称,映射它的键。显然,这个内部unordered_map
将是空的。
该类对象应使用universal hash function,由构造函数中的seed
伪随机选择。在一种创建通用散列函数的方法中查看this question的答案。
当调用操作员时,应检查名称是否在内部unordered_map
。如果是这样,请返回找到的密钥。否则,首先使用散列函数计算密钥并将其放置在内部unordered_map
中。但是,在生成新密钥时,请检查它是否与现有密钥相冲突,如果是,则引发异常。实际上,由于每个不同的名称都对应于您的代码中的一个地方,因此您呼叫typeid
,不同名称的数量(例如n)最多应该是1000年。设置m为8个字符的可能范围(2 )。
碰撞的概率是〜n /(2 m),它应该很小。因此,大多数机会是不会发生冲突,也不会抛出异常。然而,如果抛出一个,则改变种子,并再次构建该程序。预期的次数,你必须这样做(初始时间后)接近0.
好像你需要找到一个压缩算法。不知道这是否可能。 – alain
这看起来很像[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。 – molbdnilo
@molbdnilo如果你知道除了使用typeid之外的其他方法,我很乐意知道。 –