インタビューで次の質問がありました。実際に機能する実装を提供したと思いますが、より高速なより良い実装があるのか 、それとも私が見逃したトリックがあるのか 疑問に思っていました.
3 つの符号なし 30 ビット整数が与えられた場合、元の数値のいずれかと比較したときに同じ位置ビットが 1 に設定されている 30 ビット整数の数を返します。つまり、すべての 0 を列挙します。
例を挙げましょう。わかりやすくするために 4 ビットを使用します。
与えられた:
A = 1001
B = 0011
C = 0110
セットには 8 つの 4 ビット int があるため、8 を返す必要があります。セットは次のとおりです。
0011
0110
0111
1001
1011
1101
1110
1111
さて、私がどのように解決したかは、各数値を取得して一連の可能性を列挙し、すべての個別の値を数えることでした。セットを列挙する方法は、番号から始めて、それに 1 を追加してから、マスクに到達するまでそれ自体で OR することでした。数値自体がセットに含まれており、マスク (すべて 1 に設定されている) もセットに含まれています。たとえば、1001 のセットを列挙するには:
1001 = the start
1011 = (1001 + 1) | 1001
1101 = (1011 + 1) | 1001
1111 = (1101 + 1) | 1001 (this is the last value as we have reached our mask)
したがって、各番号に対してそれを行い、一意のものを数えます。
これはPythonコードです(ただし、ビット単位の操作を実行できる限り、言語は実際には問題にならないため、この質問がc/c ++にもタグ付けされている理由です):
MASK = 0x3FFFFFFF
def count_anded_bitmasks( A, B, C ):
andSets = set(
enumerate_all_subsets(A) +
enumerate_all_subsets(B) +
enumerate_all_subsets(C)
)
return len(andSets)
def enumerate_all_subsets( d ):
andSet = []
n = d
while n != MASK:
andSet.append(n)
n = (n + 1) | d
andSet.append(n)
return andSet
これで機能し、正しい答えが得られましたが、トリックを逃したかどうか疑問に思っています。問題はすべての値を列挙するのではなく、数だけを尋ねることだったので、おそらくもっと速い方法があります。最初に数値を組み合わせるか、列挙せずにカウントを取得します。ある感じです。多数のゼロを含む数値であるため、列挙は指数関数的に増加し、かなりの時間がかかる場合があります。
AB と C がある場合、A または B または C の対応するビットが 1 に設定されているビットが 1 に設定されている一連の数値のカウント。
質問を理解していない人もいます(最初に正しく質問しなかったことは役に立ちませんでした)。上記の指定された AB と C の値を使用してみましょう。
A:
1001
1011
1101
1111
B:
0011
0111
1011
1111
子:
0110
0111
1110
1111
これらのセットを組み合わせて、個別のエントリを数えます。それが答えです。値を列挙せずにこれを行う方法はありますか?
編集:質問を間違えてすみません。今修正しました。