无法迭代int的位表示

时间:2012-10-19 10:12:31

标签: c#

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

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
}

有人可以建议为什么它没有按预期工作吗?

7 个答案:

答案 0 :(得分:5)

它不起作用的原因是你要比较字符('0',值48!= 0

只需使用位运算符,使用 unsigned 数学运算来避免右移负数的复杂化:

统计所有零:

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;
}

如果您需要优化,还有更多奇特的方法。

答案 1 :(得分:2)

你只需要它。

int a = 258;
string str = Convert.ToString(a, 2);
var count = str.Where(c => c == '0').Count();

答案 2 :(得分: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,其中x集中最左边1位的所有位都位于其中。与x一起使用xy的重要零置于y(作为1),但不是前导零。然后计算x中的值,这与计算{{1}}中的重要零值相同。

答案 3 :(得分:1)

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

    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;
        }

答案 4 :(得分: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;


    }

答案 5 :(得分: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。

答案 6 :(得分: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;
} 

但这是一个糟糕的方法...为什么你想要将一个整数转换为一个String,当你没有它时呢?当然这有点棘手......

我会这样做:

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的解决方案可以获得更快,更优雅的结果!