由於值的範圍爲1-80,可能sextuplets的總數是「唯一」的一個稍微超過3億寫(準確地說300,500,200)。由於矩陣中只有6000行,因此任何六進制數的最大計數都是6000,所以計數可以很容易地適合兩個字節的整數(假設存在於C++實現中,則爲uint16_t
)。三億兩個字節的整數總共600兆字節,你可能已經有了。所以一個簡單的算法就是創建計數向量,初始化爲零,然後迭代矩陣中的所有行;對於每一行,遍歷38,760個六元組,並對每個六元組遞增相應的計數。
訣竅是計算出計數向量中的哪個元素對應給定的六個數字集合。碰巧,只要六個字符的數字從最小到最大,這並不難。 (這不是一個限制,因爲你需要有一些規範的順序爲六元組,並按順序排序是一個簡單的規範順序。)
要了解如何生成索引,請考慮如何(假設)枚舉所有300,500,200來自集合{1..80}的六個整數的組合。首先,我們列舉以1開始的組合,並繼續使用集合{2..80}中的五個整數。然後,我們枚舉以2開始的組合,並繼續使用集合{3..80}中的五個整數。然後,我們枚舉以3開始的組合,並繼續使用集合{4..80}中的5個整數。等等。在每個起點的枚舉中,我們遞歸地應用相同的算法。
現在,讓我們把它列在頭上。假設我們有一些六聯{a,b,c,d,e,f}
。請問之後有多少個六進制碼出現那sextuplet?
首先,所有以大於a
的值開始的六個字符串。由於六個字符串是有序的,如果一個六元組的起始值大於a
,那麼它的所有值都大於a
,這意味着它是來自集合{a+1..80}
的六個值的某種組合,其中有 80-a C 。
然後,所有六個字符串都以a
開頭,並繼續五元組,第一個值大於b
。通過上述相同的邏輯,這樣的六個小組的數目是 80-b C 。
然後,存在與開始a,b
並繼續四方其第一值大於c
更大所有sextuplets:共 80-C的C
等等
所以以下{a,b,c,d,e,f}
sextuplets總數恰恰是:
80-AÇ + 80-BÇ + 80-CÇ + 80-dÇ + 80-EÇ + 80-Fç
有趣關於上面的等式是,有六個變量之間沒有相互作用。我們可以通過創建六個查找表來計算值,其值爲1到80之間的值,以及i的值從1到6.然後我們可以計算(逆)指數通過只進行六次查找並將值加在一起來確定任何六進制數。 (如果需要的話,我們可以從組合總數中減去反向索引以得到正向索引,但是在這種情況下,我們需要的是從組合到整數的雙向反射,反向索引將正常工作。)
在算法結束時,有必要將計數索引變回六個字節。這可以使用相同的查找表,通過執行二進制搜索的連續操作來完成:首先,在i == 6的查找表中通過二進制搜索找到值a
,然後減去相應的索引並繼續搜索餘數i == 5的查找表等等(實際上,由於查找表很小,可能會發現線性搜索比二元搜索更快,但它可能沒有多大區別。)
決定一種語言來得到一個簡潔和正確的答案。 –
讓它成爲C++,我猜它是最快的 – Djuro
它的對,三連音... sextuplets。我需要找出六個數字的組合是最常見的 – Djuro