2

我需要遍历一个整数的位表示,然后我需要计算其中的零数。我厌倦了下面的代码,但不幸的是它不起作用:

public int calculate(int i)
{
            string a = Convert.ToString(i, 2);
            int[] array = new int[a.Length];
            int number = 0;

            for (int n = 0; n < s.Length; n++)
            {
                iarray[n] = s[n]; // build an array of intigers representing the bits valies such as 0011100
            }

            for (int n = 0; n < array.Length; n++)
            {
                if (array[n] == 0) {
                   number = number + 1;
            }

            return number
}

谁能建议它为什么不能按预期工作?

4

7 回答 7

5

它不起作用的原因是您正在比较字符('0', value 48 != 0

只需使用位运算符,使用无符号数学来避免右移负数带来的复杂性:

计算全零:

var u = (uint)i;
int count = 0;
for(int bit = 0; bit < 32; bit++)
{
    if((u & 1)==0) count++;
    u  = u >> 1;
}

只计算零直到最高有效设置位:

var u = (uint)i;
int count = 0;
while(u != 0)
{
    if((u & 1)==0) count++;
    u  = u >> 1;
}

如果您需要优化,还有更多奇特的方法可以做到这一点。

于 2012-10-19T10:16:55.163 回答
2
int SignificantZeroCount(int x)
{
    int mask = x | (x >> 16);
    mask |= mask >> 8;
    mask |= mask >> 4;
    mask |= mask >> 2;
    mask |= mask >> 1;

    int y = mask ^ x;
    int c = 0;
    while (y != 0)
    {
        c++;
        y &= y - 1;
    }
    return c;
}

首先mask计算 a 中的所有位都在集合中的最左侧 1 位的右侧和右侧x。异或将inx的重要零(作为一),但不是前导零。然后计算 中的个数,这与计算 中的有效零相同。xyyx

于 2012-10-19T10:30:08.890 回答
2

你只需要它。

int a = 258;
string str = Convert.ToString(a, 2);
var count = str.Where(c => c == '0').Count();
于 2012-10-19T10:17:07.463 回答
1

您将 ASCII 值存储在数组 [] 中。使用这样的转换来获得你想要的:

    public static int calculate(int i)
        {
            string a = Convert.ToString(i, 2);
            int[] array = new int[a.Length];
            int number = 0;
            for (int n = 0; n < a.Length; n++)
            {
                array[n] = Convert.ToInt32(a[n].ToString()); // build an array of intigers representing the bits valies such as 0011100
            }

            for (int n = 0; n < array.Length; n++)
            {
                if (array[n] == 0)
                {
                    number = number + 1;
                }
            }
            return number;
        }
于 2012-10-19T10:17:11.000 回答
0

纠正你的方法是这样的:

public int calculate(int i) {
    string a = Convert.ToString(i, 2);


    int[] array = new int[a.Length];
    int number = 0;
    for (int n = 0; n < a.Length; n++) {
        iarray[n] = int.parse(a[n]);              
    }               
    for (int n = 0; n < array.Length; n++) {
        if (array[n] == 0) {
             number = number + 1;
        }
    }
    return number;
} 

但这是一个不好的方法......当你可以不这样做时,为什么要将整数转换为字符串?当然,这有点棘手......

我会这样做:

public int calculate(int i) {
    int bits = 1+Math.log(i) / Math.log(2)
    int zerocount = 0;
    for(int j=0;j<bits;j++) {
        if(i%2==0) {
            zeroCount++;
        }
        i==i>>1;
    }
    return zeroCount;
}

编辑这也不是最好的解决方案,因为Math.log不是太快。使用 Marc 的解决方案可以获得更快、更优雅的结果!

于 2012-10-19T10:24:21.457 回答
0

尝试这个:

 public int calculate(int i)
            {
        string a = Convert.ToString(i, 2);
        int number = 0

        for (int i=0;i<a.Lenght;i++){
              if (a.Substring(i,1).Equals("0"))
                   number++;
        }

        return number;


    }
于 2012-10-19T10:17:31.440 回答
0

您可以使用以下代码:

IEnumerable<int> GetBits(int n)
{
    int m = 1;
    while(m <= n)
    {
        if((n & m) == m)
            yield return 1;
        else
            yield return 0;
        m <<= 1;
    }
}

var numberOfZeros = GetBits(42).Count(x => x == 0);

请注意,这只会返回重要的零,即数字 42 的 3。

于 2012-10-19T10:18:07.760 回答