<span style="white-space:pre"> </span>/**
* 方法:位操作法
* 思路:获取后一个较大的数
* 1)计算c0和c1。c1是拖尾1的个数,c0是紧邻拖尾1的作坊一连串0的个数。
* 2)将最右边、非拖尾0变为1,其位置为p=c1+c0。
* 3)将位p右边的所有位清零。
* 4)在紧邻位置p的右方,插入c1-1个1。
* @param n
* @return
*/
public static int getNext(int n){
int c=n;
int c0=0;
int c1=0;
while((c&1)==0&&(c!=0)){
c0++;
c>>=1;
}
while((c&1)==1){
c1++;
c>>=1;
}
if(c0+c1==31||c0+c1==0)//c0+c1+1=32,1表示p所在位。
return -1;
int p=c0+c1;//最右边处,非拖尾0的位置。
n|=(1<<p);//翻转0为1
n&=~((1<<p)-1);//将p右边的所有位清零
n|=(1<<(c1-1))-1;//在右边填入(c1-1)个1
return n;
}
/**
* 思路:获取前一个较小的数
* 1)计算c0和c1。c1是拖尾1的个数,c0是紧邻拖尾1的作坊一连串0的个数。
* 2)将最右边、非拖尾1变为0,其位置为p=c1+c0。
* 3)将位p右边的所有位清零。
* 4)在紧邻位置p的右方,插入c1+1个1。
* 注意:步骤2和3可以合并。
* @param n
* @return
*/
public static int getPrev(int n){
int c=n;
int c0=0;
int c1=0;
while((c&1)==1){
c1++;
c>>=1;
}
if(c==0)
return -1;//错误检查!!!全为1时,无法找到
while((c&1)==0&&(c!=0)){
c0++;
c>>=1;
}
int p=c0+c1;
n&=~((1<<(p+1))-1);//将最右边、非拖尾1变为0,其位置为p=c1+c0;将位p右边的所有位清零。
int mask=(1<<(c1+1))-1;//在紧邻(!!!)位置p的右方,插入c1+1个1。
n|=mask<<(c0-1);
return n;
}<span style="white-space:pre"> </span>/**
* 方法:算术法
* 思路:获取后一个较大的数,重新表述问题
* 1)计算c0和c1。c1是拖尾1的个数,c0是紧邻拖尾1的作坊一连串0的个数。
* 2)将p位置1。
* 3)将位p右边的所有位清零。
* 4)在紧邻位置p的右方,插入c1-1个1。
* 步骤2,3有一种快速做法,将拖尾0置为1(得到p个拖尾1),然后再加1。加1后,所有拖尾1都会翻转,最终位p变为1,后边跟p个0.
* @param n
* @return
*/
public static int getNextArith(int n){
int c=n;
int c0=0;
int c1=1;
while((c0&1)==0&&(c!=0)){
c0++;
c>>=1;
}
while((c1&1)==1){
c1++;
c>>=1;
}
if(c0+c1==31||c0+c1==0)
return -1;
//将拖尾0置1,得到p个拖尾1
n|=(1<<c0)-1;
//先将p个1清零,然后位p改为1
n+=1;
//在右边填入(c1-1)个1
n|=(1<<(c1-1))-1;
return n;
}
/**
* 方法:算术法
* 思路:获取前一个较小的数,重新表述问题
* 1)计算c0和c1。c1是拖尾1的个数,c0是紧邻拖尾1的作坊一连串0的个数。
* 2)将p位清零。
* 3)将位p右边的所有位置1。
* 4)将位0到位c0-1清零。
* @param n
* @return
*/
public static int getPrevArith(int n){
int c=n;
int c0=0;
int c1=0;
while((c&1)==1){
c1++;
c>>=1;
}
while((c&1)==0&&(c!=0)){
c0++;
c>>=1;
}
if(c==0)
return -1;//错误检查!!!全为1时,无法找到
n-=(1<<c1)-1;//清除拖尾1,此时p位为1,后面全部为零
n-=1;//将p为置0,后面所有位置置1
n&=~(1<<(c0-1)-1);//将最后边置c0-1个0
return n;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
9.5位操作(三)——给定一个正整数,找出与其二进制表示中1的个数相同,且大小最接近的那两个数
原文地址:http://blog.csdn.net/shangqing1123/article/details/47314713