腾讯面试题之整数二进制替换

本文介绍了一种方法,用于将整数的二进制表示中所有出现的001子串替换为011。通过左移操作避免了有符号数右移的问题,实现了高效替换。

题目:对于某个int型的整数,将其二进制表示的001替换为011


解题思路:该题为tencent面试题。能够想到的思路是讲int型数与7进行与操作,若结果为1,则进行替换,否则进入下次比较。由于int型整数A负数可能性的存在,故而不能使用将A进行右移(一般编译器对于有符号的数据的右移操作为算术移位,即最高位补最高位的拷贝,例如:负数A=0xffffffffc为-4,那么A>>1,则为-2而非0x7ffffffffe)。若是将A进行左移操作的话,那么会丢失最高位。最后合适的方法是将7进行左移,逐位与A进行与操作,若不为1,则将7左移一位。若为1,则将7左移三位,并完成001到011的替换。因为左移1位和左移2位都肯定不会和001。这里的左移多少位,和KMP算法挺像。001替换为011,我只需要改一个bit位就行了。

原理演示实例:

1 0 1 0 0 1 1 0 1 0
(1)        1 1 1  &操作结果不为1,则111左移1位;
(2)       1 1 1   &操作结果不为1,则111左移1位;
(3)      1 1 1    &操作结果不为1,则111左移1位;
(4)    1 1 1      &操作结果不为1,则111左移1位;
(5)   1 1 1       &操作结果为1,则111左移3位;
(6)  1 1 1        &操作结果不为1,则111左移1位;
(7) 1 1 1          &操作结果不为1,则111左移1位;
(8)1 1 1          &操作结果不为1,则111左移1位;

具体实现代码如下:

/*
*****************************************************
	Author:GS<song0071000@126.com>
	CreateTime:2013/8/28
	Descript:replace some bits in a num
*****************************************************
*/                                                                                                                                                                             
/*we cannot make right shift because of signed number*/                                                                                                                       
int bitreplace(int num)                                                                                                                                                       
{                                                                                                                                                                             
        int filter = 7;                                                                                                                                                       
        unsigned int shift = 0;                                                                                                                                               
        unsigned int wholeshift=0;                                                                                                                                            
        while(wholeshift<=(sizeof(int)*8-3))/*the filter can right shift 29 at most.*/                                                                                                                                                 
        {                                                                                                                                                                                                                                                                                                               
                if((num&(filter<<wholeshift))==(1<<wholeshift))/*match!*/                                                                                                          
                {                                                                                                                                                             
                        /*do replace*/                                                                                                                                        
                        num |= (1<<(wholeshift+1));/*replace 001 with 011*/                                                                                                           
                        shift =3;                                                                                                                                             
                }                                                                                                                                                             
                else
				{
					shift = 1;
				}
				wholeshift +=shift;
        }                                                                                                                                                                     
        return num;                                                                                                                                                           
}  

如有其它更好方法,欢迎讨论!

本人享有博客文章的版权,转载请标明出处http://blog.csdn.net/baidu20008

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值