簡體   English   中英

為給定的唯一數字列表/集合/數組生成唯一 ID

[英]Generating unique id for a given list/set/array of unique numbers

我有 arrays 包含從 0 到 integer.max 值的隨機唯一數字。

我如何生成唯一的 id/signature(int) 來唯一地標識每個數組,而不是搜索每個數組並檢查每個數字。

例如

int[] x = {2,4,8,1,88,12....};
int[] y = {123,456,64,87,1,12...};
int[] z = {2,4,8,1...};
int[] xx = {213,3534,778,1,2,234....};
..................
..................
and so on.

每個數組可以有不同的長度,但數字在數組內不重復,可以在其他 arrays 中重復。 每個數組唯一的 id 的目的是通過 id 來識別它,以便快速進行搜索。 arrays 包含組件的 ID,陣列的唯一簽名/ID 將識別其中包含的組件。

此外,無論數組中值的順序如何,生成的 id 都應該是相同的。 像 {1,5} 和 {5,1} 應該生成相同的 id。

我查找了不同的數字配對方法,但是隨着數組的長度增加到無法放入 int 的程度,結果數字也會增加。

分配給組件的 IDS 可以調整,它們不必是整數序列,只要有合適的數字范圍即可。 唯一的要求是,一旦為數組(組件 id 的集合)生成了 id,它們就不應發生沖突。 如果該數組中的集合發生更改,則可以在運行時生成。

這可以通過 hash function h()和順序歸一化 function (例如sort() )來近似解決。 A hash function 是有損的,因為唯一散列的數量(2^32 或 2^64)小於可能的可變長度整數集的數量,導致兩個不同集具有相同 ID 的可能性很小(散列沖突)。 通常這不會是一個問題,如果

  • 你使用一個好的 hash function,和
  • 你的數據集不是大得離譜。

順序規范化 function 將確保集合 {x, y} 和 {y, x} 被散列到相同的值。

For the hash function you have many options, but choose a hash that minimizes collision probability, such as a cryptographic hash (SHA-256, MD5) or if you need bleeding edge performance use MurmurHash3 or other hash du jour. MurmurHash3 can produce an integer as output, while the cryptographic hashes require an extra step of extracting 4 or 8 bytes from the binary output and unpacking to an integer. (使用任何一致的字節選擇,例如第一個或最后一個。)

在偽代碼中:

int getId(setOfInts) {
    intList = convert setOfInts to integer list
    sortedIntList = sort(intList)
    ilBytes = cast sortedIntList to byte array
    hashdigest = hash(ilBytes)
    leadingBytes = extract 4 or 8 leading bytes of hashdigest
    idInt = cast leadingBytes to integer
    return idInt
}

嚴格來說,您所要求的是不可能的:即使只有兩個元素的 arrays ,也有更多可能的 arrays (忽略順序后約 2 61 )比可能的簽名( 2 32 )。 而且您的 arrays 不限於兩個元素,因此您的情況呈指數級惡化。

但是,如果您可以接受較低的重復率和錯誤匹配率,那么一種簡單的方法是使用+運算符將所有元素相加(這實際上是計算模 2 32的總和)。 這是 java.util.Set<Integer> 的 hashCode() 方法所采用的方法。 它並不能完全消除比較整個 arrays 的需要(因為您需要檢測錯誤匹配),但它會從根本上減少此類比較的數量(因為很少有 arrays 會匹配任何給定的數組)。

您希望 {1, 5} 和 {5, 1} 具有相同的 ID。 這排除了標准 hash 函數,在這種情況下會給出不同的結果。 一種選擇是在散列之前對數組進行排序。 請注意,加密哈希很慢; 您可能會發現像 FNV 這樣的非加密 hash 就足夠了。 它肯定會更快。

為避免排序,只需添加所有數字 mod 2^32 或 mod 2^64,正如@ruakh 建議的那樣,並接受您將有一定比例的碰撞。 添加數組長度將避免一些沖突:在這種情況下 {5, 1} 將不匹配 {1, 2, 3} 為 (2+(5+1)).= (3+(1+2+3) )。 您可能想用您的真實數據進行測試,看看這是否有足夠的優勢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM