一般來說,建立一個將任意長度的字符串映射到固定域的函數是不可能的。這違反了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之外的其他方法,我很樂意知道。 –