我正在使用基本轉換算法從大整數(拆分爲32位單詞)生成一個置換。大型整數加速「基本轉換」
我用一個比較標準的算法是:
/* N = count,K is permutation index (0..N!-1) A[N] contains 0..N-1 */
i = 0;
while (N > 1) {
swap A[i] and A[i+(k%N)]
k = k/N
N = N - 1
i = i + 1
}
不幸的是,分而模每次迭代增加了,尤其是轉移到大的整數 - 但是,似乎我可以只使用乘法!
/* As before, N is count, K is index, A[N] contains 0..N-1 */
/* Split is arbitrarily 128 (bits), for my current choice of N */
/* "Adjust" is precalculated: (1 << Split)/(N!) */
a = k*Adjust; /* a can be treated as a fixed point fraction */
i = 0;
while (N > 1) {
a = a*N;
index = a >> Split;
a = a & ((1 << Split) - 1); /* actually, just zeroing a register */
swap A[i] and A[i+index]
N = N - 1
i = i + 1
}
這是更好,但做大整數乘法仍然呆滯。
問題1:
有沒有更快的方法?
例如,既然我知道N *(N-1)小於2^32,我可以從一個單詞中提取這些數字,併合併到「剩菜」中嗎?
或者,有沒有辦法修改一個合法的解碼器來逐個提取指示符?
問題2:
爲了好奇 - 如果我使用乘法將數字轉換爲基數10而不進行調整,則結果乘以(10^digit/2^shift)。是否有一個棘手的方法來消除這個因素與小數位?即使有調整因素,這看起來會更快 - 標準庫爲什麼不使用這個vs divide和mod?
我無法理解你的第二個算法。 – 2010-11-25 13:16:08
@GregS - 請告訴我,如果您認爲存在問題 - 理論上它會使用乘法/面具從右側(msb)中去除值,而使用mod/divide去除右側(lsb)中的值。 – 2010-11-25 18:13:32