461. Hamming Distance的C++解法

我自己最初的解法,愚蠢至极:

class Solution {
public:
	int hammingDistance(int x, int y) 
	{
	  int x1[32];
	  int x2[32];
	  int i = 31;
	  int sum=0;
	  for (i; i >=0; i--)
	   {
		   x1[i] = x % 2;
		   x = x / 2;
		   
		   x2[i] = y % 2;
		   y = y / 2;
		   
	    }
	  for (i = 0; i <= 31; i++)
		  if (x1[i] != x2[i]) sum = sum + 1;
	  return sum;
	}
};
 


最优解关键:

C++中把int型作为二进制数,可以直接使用 ^异或、&与、>>右移、<<左移等位运算符对int进行操作:问题转化为怎样最快计算一个二进制数中1的个数。

异或:2^4=6 (010^100=110)

左移:将一个位信息串向左移指定的位,右端用0补充,左端移出的位被丢弃。在信息没有丢失的情况下每左移一位相当于*2。

右移:将一个位信息串向右移指定的位,右端移出的位被丢弃。左端:无符号数用0补充有符号正数(符号位为0)用0补充有符号负数(符号位为1)取决于计算机系统(用0补充的系统为逻辑右移,用1补充的系统为算术右移)。但问题是计算机里的数都是按补码(有符号数取反取补符号位都不变)存的,所以在C++运行 -2>>1会输出-1。



需要考虑的问题:

数字的符号。


方法一:两个数做异或之后得到tmp。先判断符号,把数字统一成正数。每次最后一位和1做与运算,计数。

int CountOne(int tmp)  
{  
int count=0;  
if(0==tmp)  
return count;  
else if(tmp>0)  
{  
    while(tmp)  
  {  
  if(tmp&1)  
    ++count;  
  tmp=tmp>>1;  
  }  
}  
else  
{  
tmp=-tmp;  
count=1;  
while(tmp)  
  {  
  if(tmp&1)  
    ++count;  
  tmp=tmp>>1;  
  }  
}  
return count;  
} 

方法二:不对异或结果tmp进行右移,反之对用来做与运算的“1”进行左移。可以不用判断符号。

int CountOneVersion2(int tmp)  
{  
int flag=1;  
int count=0;  
while(flag)  
{  
if(flag&tmp)  
++count;  
flag=flag<<1;  
}  
return count;  
}  


方法三:

为奇数(n的二进制表示的末位为1): 
n:       xxxxxxxx1 
n-1:     xxxxxxxx0 
n&(n-1): xxxxxxxx0 
相当于去掉最右边的一个1。 

n为偶数且不等于0(n的二进制表示的末位为0): 
n:       xxxxx1000 
n-1:     xxxxx0111 
n&(n1-): xxxxx0000 
也是相当于去掉最右边的一个1。

一直循环直到为0,即为所有1的个数。

int CountOneVersion3(int n)  
{  
int count=0;  
while(n)  
{  
++count;  
n=n&(n-1);  
}  
return count;  
} 


方法四:计算快速汉明距离

看不懂原理,先存着。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值