給定兩個正整數(二進制形式表示)A和B,問把A變為B需要改變多少位(bit)?也就是說,整數A和B的二進制表示中有多少位是不同的?


解法一:舉例說明,為了減少復雜度,就使用八位二進制吧。設 A = 0010 1011, B = 0110 0101.
1. C = A & B = 0010 0001;
2. D = A | B = 0110 1111;
3. E = C ^ D = 0100 1110;
4. 結果E中有4個1,那么也就是說將A變成B,需要改變4位(bit)。
至於如何判斷E的二進制表示中有幾個1,可以采用快速移位與方法。
算法原理如下:
1. A & B,得到的結果C中的1的位表明了A和B中相同的位都是1的位;
2. A | B, 得到的結果D中的1的位表明了A和B在該位至少有一個為1的位,包含了A 與 B 都是1的位數,
經過前兩步的位運算,,C 中1的位表明了A 和 B在該位都是1,D中為0的位表明了A 和 B 在該位都是0 ,所以進行第三步。
3. C ^ D,E 中為1的位表明了A 和 B不同的位。

代碼:

#include<iostream>
using namespace std;
int getNum(int n)
{
    if(n==0) return 0;
    int count=0;
    while(n)
    {
        n&=(n-1);
        count++;
    }
    return count;
} 
int main()
{
    int A=43,B=101;
    int C=A&B;
    int D=A|B;
    int E=C^D;
    cout<<getNum(E)<<endl;
    system("pause");
    return 0;
}

解法二:

思路:對於給定的兩個數,從最低位開始掃描,分別找到A和B的第一個“1”出現的位置,n1和n2
1. n1==n2,將n1(n2)位置0,繼續往高位找;
2. n1<n2, 說明A的n1位為1,但B的n1位為0,num++;將A的n1位置0,繼續尋找A的下一個1的位置;
3. n1>n2, 同2)反之。

代碼:

int count(int a, int b)
{
    unsigned int n1,n2,num=0;
    n1=a-(a&(a-1));
    n2=b-(b&(b-1));
    while((n1!=0)&&(n2!=0))
    {
        if(n1==n2)
        {
            a&=~n1;
            b&=~n2;
            n1=a-(a&(a-1));
            n2=b-(b&(b-1));
        }
        else
        {
            num++;
            if(n1<n2)
            {
                a&=(~n1);
                n1=a-(a&(a-1));
            }
            else
            {
                b&=(~n2);
                n2=b-(b&(b-1));
            }
        }
    }
    while(n1!=0)
    {
        num++;
        a&=(~n1);
        n1=a-(a&(a-1));
    }
    while(n2!=0)
    {
        num++;
        b&=(~n2);
        n2=b-(b&(b-1));
    }
    return num;
}

復雜性分析:始終在追蹤“1”,因此復雜性為O(V(A|B)),V(A|B)為A|B中的“1”的個數。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM