位运算

位运算有五种:与、或、异或、左移、右移;

与(&):两个都为1时才为1;其他都为0。
或(|):有一个为1就为1;其他为0.
异或(^):两个相同为0,不同为1.
左移(>>):左移n位,则高位(左边)去掉n,低位(右边)补0.相当于乘以n个2.
右移(>>):右移n位,无符号位整数:去掉低位(右边)的n位,高位补0.
有符号整数:正数:去掉低位n位,左边补0.负数:左边补1(负数在计算机中二进制呈补码形式:补码,正数二进制,按位取反,加1)。右移相当于除以n个2.

题目:正数n的二进制中1的个数。

解法一:可以用与1(1的二进制中1的前面全是0)做与运算来判断n的最低位是不是为1 ,接着把1左移一位得到2(0010),在与n做为运算,就能判断n的次位是不是为1,如此反复,即可求出1的个数。

代码如下:

//求一整数中的二进制表示1的个数 ,循环次数为整数二进制的位数,如果32位,则循环32次
    static int NumberOf1(int n) {
        int num = 0;
        int falg = 1;
        while(falg!=0) {
            if((n&falg)!=0)
                num++; 
            falg = falg<<1;
        }
        return num;
    }

第二种算法:

把一个整数减去1,再和原来的整数做与运算,会把该整数二进制表示的最右边的一个1变为0.那么一个整数的二进制中有多少个1,就可以进行多少次这样的运算。

基于这种思想,代码如下:

//优质算法,有几个1,循环几次
    static int NumberOf1Nice(int n) {
        int num = 0;
        while(n!=0) {
            num++;
            n = (n-1) & n;
        }
        return num;
    }

输入两个整数n和m,计算需要改变m的二进制表示多少位才能得到n,比如10的二进制位1010,13的二进制为1101,需要改变1010中的三位才能得到1101。
解决此问题的方法:可以先做m与n的异或运算,在求出1的个数,即为改变了m二进制的多少位。

扩展问题:

在Excel2003中,用A表示1第一列,用B表示2第二列……用Z表示第二十六列,用AA表示第二十七列,用AB表示第二十八列….以此类推。写出一个函数,输入用字母表示的列号编码,输出他的列号,如输入AA,输出27.

解法:题目本质是把十进制数字用A~Z表示成了二十六进制的了

代码如下:

 static int index(String str) {
        int index = 0;
        if(str == null) {
            return -1;
        }
        String excel = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int slen = str.length();
        for(int i=0;i<str.length();i++){
        //如果输入ABC,先A开始
            char x = str.charAt(i);
            //如果出现小写字母,输入错误,直接退出,A=65 Z=90
            if(x<65 || x>90 ) return -1;
            for(int j=0;j<excel.length();j++) {
                //求出C所表示的权重(即列号+1,+1因为数组是从0开始编号的)
                if(x==excel.charAt(j)) {
                    //index : ABC = 1*26^2 + 2*26^1 + 3*26^0
                    index += (j+1)*Math.pow(26, --slen);
                    break;
                }
            }
        }
        return index;
    } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值