正の整数をテストして、バイナリ表現が 0 個以上の 1 で始まり、その後に 1 個以上の 0 が続くかどうかを確認したいと考えています。
00000000 // Valid
10000000 // Valid
11000000 // Valid
11100000 // Valid
11110000 // Valid
11111100 // Valid
11111110 // Valid
11111110 // Valid
11111111 // Not Valid
// Any other combination is Not Valid
同じものを正規表現で表現すると、^[1]*[0]+$ になります。もちろん、これは説明のためだけのものであり、正規表現は使用できません。
ブルートフォースは次のようにアプローチします。
- 複数のビット マスクを作成し、AND を組み合わせて結果を決定します。
- 動的マスクを使用して各桁をループし、結果を決定します。
問題は、数十万桁の巨大な正の整数を扱っており、そのような数千の数に対してこのテストを実行する必要があることです。
このバイナリ パターンを決定するより効率的な方法はありますか?
アップデート
これが私が試した実装です。まだ他の回答と時間を比較していません。
public static bool IsDiagonalToPowerOfTwo (this System.Numerics.BigInteger number)
{
byte [] bytes = null;
bool moreOnesPossible = true;
if (number == 0) // 00000000
{
return (true); // All bits are zero.
}
else
{
bytes = number.ToByteArray();
if ((bytes [bytes.Length - 1] & 1) == 1)
{
return (false);
}
else
{
for (byte b=0; b < bytes.Length; b++)
{
if (moreOnesPossible)
{
if (bytes [b] == 255)
{
// Continue.
}
else if
(
((bytes [b] & 128) == 128) // 10000000
|| ((bytes [b] & 192) == 192) // 11000000
|| ((bytes [b] & 224) == 224) // 11100000
|| ((bytes [b] & 240) == 240) // 11110000
|| ((bytes [b] & 248) == 248) // 11111000
|| ((bytes [b] & 252) == 252) // 11111100
|| ((bytes [b] & 254) == 254) // 11111110
)
{
moreOnesPossible = false;
}
else
{
return (false);
}
}
else
{
if (bytes [b] > 0)
{
return (false);
}
}
}
}
}
return (true);
}