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', 値 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 a = 258;
string str = Convert.ToString(a, 2);
var count = str.Where(c => c == '0').Count();
于 2012-10-19T10:17:07.463 に答える
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、セット内の左端の 1 ビットとその右側のすべてのビットを持つ a が計算さxれます。これを Xor リングすると、 inxの有意なゼロが(1 として) 配置されますが、先頭のゼロは配置されません。次に、 の 1がカウントされます。これは、 の有意なゼロをカウントするのと同じです。xyyx

于 2012-10-19T10:30:08.890 に答える
1

array[] に 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 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

アプローチを修正すると、次のようになります。

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速すぎないため、どちらも最善の解決策ではありません。マークのソリューションを使用して、はるかに迅速でエレガントな結果を得ることができます!

于 2012-10-19T10:24:21.457 に答える
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 に答える