【发布时间】:2012-08-02 19:21:45
【问题描述】:
我想测试一个正整数,看看它的二进制表示是否以零个或多个 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]+$。当然这只是为了澄清,我们不能使用正则表达式。
蛮力逼近:
- 创建多个位掩码,并一起确定结果。
- 使用动态掩码遍历每个数字以确定结果。
问题是我正在处理可能有数十万位数字的巨大正整数,并且需要对数千个这样的数字执行此测试。
有没有更有效的方法来确定这种二进制模式?
更新
这是我尝试过的实现。尚未将时间与其他答案进行比较。
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);
}
【问题讨论】:
-
您实际上是将它们用作整数,还是仅用作位存储?坦率地说,如果这些是唯一有效的集合,我会使用不同的表示,即“个数,零个数”。当然,如果你需要做算术等,那是行不通的。
-
我不知道什么是HUME大整数,这在.net上是如何表示的?我想 ubyte/uint/etc 的数组……是这个吗? @MarcGravell 已经问过了,但是你是在用这些数据做一些算术还是只是一个表示?
-
@devundef:我的错误。它应该是 HUGE/LARGE,而不是 HUME。
-
提示:不要使用扩展方法,每次调用该方法时,都会在内存中生成一个巨大整数的副本;尽可能使用“ref”。
标签: c# .net binary numbers bit-manipulation