一、智者说:无聊的时候来几道算法题,可以训练训练自己的思维嘛!难怪之前人家说数学好的人编程起来事半功倍,写算法的过程中真是深有体会啊!感觉就像是在做大学的高数题......本博文仅用来记录自己学习算法的历程,不定时更新。参考自《编程之美》,加上些自己的理解。有啥不对的地方,还请大家不吝指教!
二、求二进制数中1的个数(对于一个字节(8bit)的变量,求其二进制中"1"的个数,要求算法的执行效率尽可能高)
public class One { public static void main(String[] args) { int v = 0b10101010; System.out.println(count(v)); System.out.println(count2(v)); System.out.println(count3(v)); } /*解法一:对于2进制来说,把他除以2就是向左移了一位,余数为0,代表最后一位为0。余数为1,代表最后一位为1*/ public static int count(int v) { int count = 0; while (v != 0) { if (v % 2 == 1) { count++; } v = v / 2; } return count; } /*解法二:使用位操作,每次向右移动1位,即抛弃一位。跟00000001进行与运算判断是否为1*/ public static int count2(int v){ int count=0; while (v!=0){ count += v & 0B00000001; v=v>>1; } return count; } /*解法三:前面两种解法的时间复杂度都是O(log2n),通过二进制数每次和(二进制-1)进行与运行,都会使二进制中少了一个1*/ public static int count3(int v){ int count=0; while (v!=0){ v=v&(v-1); count++; } return count; } /*拓展题:给定两个正整数(二进制表示的A和B),请问把A变成B需要改变多少位?也就是说A和B的二进制表示中有多少位是不同的 * 原理: * 1. A & B,得到的结果C中的1的位表明了A和B中相同的位都是1的位; * 2. A | B, 得到的结果D中的1的位表明了A和B在该位至少有一个为1的位,包含了A 与 B 都是1的位数,经过前两步的位运算,,C 中1的位表明了A 和 B在该位都是1,D中为0的位表明了A 和 B 在该位都是0 ,所以进行第三步。 * 3. C ^ D,E 中为1的位表明了A 和 B不同的位。 * */ public static int diff(int A,int B){ int sum=0; int C = A & B; int D = A | B; int E = C ^ D; sum=count2(E); return sum; } }