2011-09-18 9 views
3

4つの整数a≤b≤cとkが与えられた場合、バイナリ表現が正確にk位置が異なる[a、c] Bのそれ? a、b、cは約30ビットです。バイナリ表現が指定された整数とちょうどkの位置が異なるカウント整数

+0

ダイナミックプログラミングに精通していますか?私は、O(log(C)* K)で実行されるアルゴリズムのスケッチをいくつか持っています。これは、基本的に、Nを計算するdp algのより複雑なバージョンですが、時間O(N * K) <=条件を処理するためにbとcのビット単位の表現。 –

+0

以下のコメントに書いたように、すべてのkに対してこの数が必要であると付け加えることができます。これは質問(および回答)を大きく変えます。一度に一度に一度に一度に効率的に処理されるものもあります。 –

答えて

0

bのバイナリreprを書き、そのビットを反転して境界に違反していないかどうかを確認します。 a、bが30ビットの場合、kが妥当である限り、シェルスクリプトやCプログラムを記述することは禁忌ではありません。

+0

最悪の場合、C(30,15)≒155百万の数値をチェックする必要があるため、このアルゴリズムは実現できない可能性があります。 – Pteromys

+0

@Peromys1.5百万は実際にそれほど悪くはありません。妥当な定数では、1億5,500万の数値を調べるには、1〜2秒かかります。 (真実、それは本当です) – quasiverse

+0

@quasiverseそれは本当ですが、5秒以内にすべての可能な値を数えなければなりません。 – Pteromys

1

acの間のすべての値を明示的に列挙して、値ごとにいくつのビットが異なるかをチェックするのはなぜですか?この情報理論の技術用語は、 http://en.wikipedia.org/wiki/Hamming_distance

+0

'a'と' c'は約30ビットですから。つまり、潜在的に10億の数を列挙しなければならない可能性があります。 – quasiverse

0

であり、bと正確にkの位置が異なり、多くとも30ビットで書かれた合計数はbinomial(30, k)である。この数は、k = 15で最大値がbinomial(30, 15) = 155117520なので、aからenumaratingする方が良いですが、依然として多くなる可能性があります。しかし、kが小さければそれは方法です - ちょうどkビットで異なるこれらの数をすべて列挙し、それらがaとcの間にあるかどうかをチェックしてください。 これが遅すぎる場合は、より賢明に実行する必要があります。たとえば、aとcの最高ビットが同じ場合、このビットを設定する必要があるため、可能性を減らすことができます。

1

与えられたa、b、cの数とkのすべての値を計算する必要がある場合は、xor'edの差のビット数を反復して数えることをお勧めします。

for (int i = a; i <= c; i++) { 
    int d = i^b; 
    int k = 0; 
    while (d != 0) { 
     k++; 
     d &= (d - 1); 
    } 
    counts[k]++; 
} 

これを簡単に並列化することもできます。あなたは、スレッドごとにカウントを別々にして、総計を得るためにそれらをすべて最後に追加する必要があります。

このアルゴリズムの並列バージョンは、私のマシンで3.7秒かかりました。

編集:実際には、列挙せずにカウントを取得する方法があります。ここでは、(a、b、c)=(17,25,29)、またはバイナリ(10001,11001,11101)の基本的な考え方を示します。まず、範囲11000〜11011にはbが含まれ、(a、c)にも完全に含まれていることに注意してください。したがって、これらの2^2値は、各カウントにchoose(2、k)を与えます。次の間隔は10100〜10111です。この範囲の数値はすべてbと少なくとも2ビット異なるので、k番目のcountにchoose(2、k-2)を与えます。 (a、c)に完全に含まれる次の間隔は、choose(1、k-1)などに寄与する10010〜10011です。また、上向きに数えなければなりません。

2回目の編集:これを実装することに抵抗できませんでした。 10億回の合計時間:0.004ms ...

関連する問題