大きな整数(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未満であることを知っているので、それらの数字を1つの単語から取り出し、残りの部分をマージできますか?
または、一度に1つずつインディペンデントを引き出すためのアーティチョークデコーダーを変更する方法はありますか?
質問2:好奇心の便宜上
- I変換する乗算を使用する場合、数は調整せずに10を底とするが、その結果は、(10 ^桁/ 2 ^シフト)が乗算されます。小数点を扱うこの要素を削除する手間のかかる方法はありますか?調整の要素があっても、これは速くなるように思えます。なぜ、標準ライブラリがこのvs divideとmodを使用しないのですか?
私はあなたの2番目のアルゴリズムを理解できません。 –
@GregS - 問題があると思うかどうか教えてください。理論は、mod/divideを使って、乗算/マスクと右(lsb)の値を左から取り除くというものです。 –