程序员面试金典: 9.5位操作 5.5编写一个函数,确定需要改变几个位,才能将整数A转成整数B

来源:互联网 发布:淘宝拍立淘不能用了 编辑:程序博客网 时间:2024/06/10 22:06
#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 11011011 01011111 1111输出:230关键: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;}

0 0