#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
/*
问题:编写一个函数,确定需要改变几个位,才能将整数A转成整数B。
问题:这个好像记得需要用到 ( n & (n-1)) == 0。
找规律: A: 1011 , B:1101 , 那么需要变换两次, 将两个整数进行异或处理。
1011
1101
异或: 0110
两数异或后的结果,然后统计1的个数即可
那么问题转化为如何统计1个整数中1的个数,设这个整数为num:
用 num & 1 == 1来判断,然后令 num >>= 1(向右移动),直到num变为0,这个时间复杂度为O(n),n为整数的二进制长度
如果用 ( num & (num-1) ) != 0,就累加1个个数,则时间复杂杜伟O(k),k为该整数中1的个数,
之所以: num & (num-1),并且后续循环令num = num & (num -1),是因为这样每次会消去最低位的1
输入:
1011 1101
1011 0101
1111 1111
输出:
2
3
0
关键:
1 两数异或后的结果,然后统计1的个数即可
那么问题转化为如何统计1个整数中1的个数,设这个整数为num:
用 num & 1 == 1来判断,然后令 num >>= 1(向右移动),直到num变为0,这个时间复杂度为O(n),n为整数的二进制长度
2 如果用 ( num & (num-1) ) != 0,就累加1个个数,则时间复杂度为O(k),k为该整数中1的个数,
之所以: num & (num-1),并且后续循环令num = num & (num -1),是因为这样每次会消去最低位的1,
通过不断翻转最低有效位,计算多少次c才会变成0,操作c=c & (c-1)会清除c的最低有效位
*/
typedef struct Result
{
Result(){}
Result(const Result& other){ *this = other; }
Result(bool isResult , int result):_isResult(isResult) , _result(result){}
bool _isResult;
int _result;
}Result;
Result toTenRadix(string& sNum)
{
if(sNum.empty())
{
return Result(false,-1);
}
//字符串逆序遍历,累加即可
int sum = 0;
int size = sNum.size();
int value = 0;
int count = 0;
for(int i = size - 1 ; i >= 0 ; i--)
{
if( '0' <= sNum[i] && sNum[i] <= '9')
{
value = sNum[i] - '0';
sum += value * ( (int) pow(2 , count));
}
else
{
return Result(false , -1);
}
count++;
}
return Result(true, sum);
}
int count1(int num)
{
if(0 == num)
{
return 0;
}
int count = 0;
while( ( num & (num-1)) != 0 )
{
count++;
num &= (num - 1);
}
count++; //最后一次退出一定是因为相与为0,此时包含1个1,需要累加
}
int getChangeTimes(int numA , int numB)
{
int resultNum = numA ^ numB;
//统计1的个数
int count = count1(resultNum);
return count;
}
void process()
{
string sA , sB;
Result A, B;
int times = 0;
while(cin >> sA >> sB)
{
//转换为十进制
A = toTenRadix(sA);
B = toTenRadix(sB);
//接下来统计
times = getChangeTimes(A._result , B._result);
cout << times << endl;
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}