我将使用一种进制转换算法,从一个大整数中(分成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^digits/2^shift)。是否有一种巧妙的方法来处理十进制数字而不需要这个因子?即使考虑了调整因子,这似乎也会更快--为什么标准库不使用这种方法而使用除法和取模?