Bit Hack Misc


http://blog.csdn.net/morewindows/article/details/7354571
变换符号只需要取反后加1即可
  1. int SignReversal(int a)  
  2. {  
  3.     return ~a + 1;  
  4. }  
求绝对值
  1. int my_abs(int a)  
  2. {  
  3.     int i = a >> 31;  
  4.     return i == 0 ? a : (~a + 1);  
  5. }  
对于任何数,与0异或都会保持不变,与-1即0xFFFFFFFF异或就相当于取反。因此,a与i异或后再减i(因为i为0或-1,所以减i即是要么加0要么加1)也可以得到绝对值。所以可以对上面代码优化下:
  1. int my_abs(int a)  
  2. {  
  3.     int i = a >> 31;  
  4.     return ((a ^ i) - i);  
三. 位操作与空间压缩
要压缩素数表的空间占用,可以使用位操作

http://segmentfault.com/a/1190000003789802
> 不用额外的变量实现两个数字互换。
def swap(num_1, num_2):
    num_1 ^= num_2
    num_2 ^= num_1
    num_1 ^= num_2
    return num_1, num_2
证明很简单,我们只需要明白异或运算满足下面规律:
  • 0^a = a;
  • a^a = 0;
  • a^b^c = a^c^b;
巧妙运用异或可以高效解决很多问题,比如 找出数组中只出现了一次的数(除了一个数只出现一次外,其他数都是出现两次),以及它的升级版:数组中只出现1次的两个数字(百度面试题)
> 不用判断语句来实现求绝对值。
def bit_abs(num):
    negative = num >> 31
    return (num ^ negative) - negative
这里假设程序运行环境中操作系统为32位,int型整数(不考虑整数溢出)用32位存储,因此可以用 num>>31 取出符号位,后面的部分留给大伙证明。
Divide two integers without using multiplication, division and mod operator.
就是说不用乘法,除法,求模运算来实现两个整数相除,看起来很简单,我可以用除数减去被除数,直到除数小于被除数,记录减法操作的次数即可。假设是计算m/n,那么时间复杂度为O(m/n)。用Python实现后,Time Limit Exceeded。我们考虑有没有更加优化的算法呢?
我们对除数减去被除数的过程稍作改进。假设求m/n,我们不一次次的 m-n,而是找到n的一个倍数,使得m-x*n尽可能小,这样能减少循环减法的次数,进而提高效率。我们知道在按位操作中,n << k相当于 n * 2^k,因此可以用2^k 来找合适的x。
我们需要这样的一个数字k,它使得n 2^k < m < n 2^(k+1), 然后用m - n*2^k,得到新的m'。再找相应的k',做减法,如此循环即可
http://brokendreams.iteye.com/blog/2084088
要求不用加减符号(包括负号)来实现加减法。
第1位的值有4种,0+0=0、1+0=1、0+1=1、1+1=0,这正好符合“异或”的情况。 
        第2位的值来自于第一位的进位加上本身的值,进位的情况也有4种,0+0=0、1+0=0、0+1=0,1+1=1,这正好符合“与”的情况。 
        考虑一般性,a+b就等同于a^b + (a&b) << 1,而这又是一个加法,可递归求解,出口就是当进位为0的时候。
  1. public static int add(int a, int b){  
  2.         return b == 0 ? a : add(a ^ b ,(a & b) << 1);  
  3.     }  

那么减法怎么搞呢?减法也能用加法表示嘛,比如a-b就等于a+(-b),但不能出现负号,我们知道Java中整型数值编码方式为补码,所以一个数对应的负数就这个数“取反加1”,
  1. public static int sub(int a, int b){  
  2.         return add(a, add(~b, 1));  
  3.     }  
http://codesam.blogspot.com/2011/01/bit-manipulation-tips-and-tricks-part-1.html
1. Multiply a number by a power of two using bit left shift
a << b = a * 2^b
2. Divide a number by a power of two using bit right shift
a >> b = a / 2^b
3. Toggle a specified bit in a bit string without effecting other bits
bit_string = bit_string ^ (1 << positionOfBitToToggle)
4. Checking if a bit is on or off without affecting other bits
int isAvailable (int bitString, int targetNum)
{
  return bit_string & (1 << targetNum);
}
http://codesam.blogspot.com/2011/01/bit-manipulation-tips-tricks-part-2.html
1. Turning a bit off without affecting other bits
turnBitOff (int bitString, int bitPosition)
{
  return bitString & ~(1 << bitPosition);
}
2. Turning a bit on without affecting other bits
turnBitOn (int bitString, int bitPosition)
{
  return bitString || (1 << bitPosition);
}
http://www.1point3acres.com/bbs/thread-73742-1-1.html
再准备面试的时候总结了一下关于bit manipulation可能用到的东西。在这里和大家分享一下~
x ^ 0s = x      x & 0s = 0   x | 0s = x
x ^ 1s = ~x   x & 1s = x    x | 1s = 1s
x ^ x  = 0      x & x = x     x | x  = x

boolean getBit(int i, int num){
        return ( (num & (1 << i)) != 0 );
}

int setBit(int i, int num){
        return num | (1 << i);
}

int clearBit(int num, int i) {
        int mask = ~(1 << i);
        return num & mask;
}

int clearBitMSBthroughI(int num, int i){
        int mask = (1<< i) -1;
        return num & mask;
}

int clearBitsIThrough0(int i, int num) {
        int mask = ~( (1 << (i+1) )  -1 );
        return num & mask;
}

int updateBit(int i, int num, int v){
        int mask = ~(1 << i);
        return (num & mask) | (v << i);
}
http://blog.csdn.net/earthma/article/details/46762943
值为1且最靠右的位元置为0 (如果存在): 0101 1110 => 010 1100 : x&(x-1)
值为0且最靠右的位元置为1 (如果存在): 0101 1110 => 010 1111 : x|(x+1)
将尾部的所有连续的1置为0(如果存在): 0101 0111 => 0101 0000 : x&(x+1)
将尾部的所有连续的0置为1(如果存在): 0101 1000 => 0101 1111 : x|(x-1)
将最靠右的0置为1(如果存在),且其他位元置为0: 0101 0111 => 0000 1000 :  ~x&(x+1)
将最靠右的1置为0(如果存在),且其他位元置为1: 0101 1000 => 1111 0111 : ~x|(x-1)
将尾部的连续0置为1(如果存在),且其他位元置为0: 0101 1000 => 0000 0111 : ~x&(x-1) or ~(x|-x) or (x&-x)-1
将尾部的连续1置为0(如果存在),且其他位元置为1: 0101 0111 => 1111 1000 : ~x|(x+1)
保留最右的1(如果存在),其他位元置为1: 0101 1000 => 0000 1000 :x&(-x)
最靠右的1及其右边的位元置为1,左边置为0: 0101 1010 => 0000 1111 : x^(x-1)
最靠右的0及其右边的位元置为1,左边置为0: 0101 1010 => 0000 0111 : x^(x+1)
右侧首个连续的1置为0: 0101 1100 => 0100 0000 (((x|(x-1))+1&x)  or ((x&-x)+x)&x


进阶:
求比某个数大且位元1的个数相同的数 例如 xxx0 1111 0000 => xxx1 0000 0111
令 x = xxx0 1111 0000
s = x&-x
r = s+x
y = r | ( ( x ^ r ) << 2 / s)

两数的平均数:
(x&y) + ((x^y)>>1) 下取整
(x|y)   - ((x^y)>>1) 上取整

统计位元‘1’的个数:
1.二分搜索法:
x = (x & 0x5555 5555) + ((x>>1) & 0x5555 5555)
x = (x & 0x3333 3333) + ((x>>2) & 0x3333 3333)
x = (x & 0x0F0F 0F0F) + ((x>>4) & 0x0F0F 0F0F)
x = (x & 0x00FF 00FF) + ((x>>8) & 0x00FF 00FF)
x = (x & 0x0000 FFFF) + ((x>>16) & 0x0000 FFFF)
例举一个八位数:
x = 1 0 1 1 1 1 0 0  
x1 = 01 10 10 00
x2 = 0011 0010
x3 = 00000101 = 5
上述代码中有多余的与操作
可以写成如下简单代码:
int pop(unsigned x){
x = x - ((x>>1) & 0x5555 5555)
x = (x & 0x3333 3333) + ((x>>2) & 0x3333 3333)
x = (x+(x>>4)) & 0x0F0F 0F0F
x = x+(x>>8)
        x = x + (x>>16)
return x& 0x0000 003F
}
第一行中x的值是由以下公式而来:
pop(x) =  x - [x/2] - [x/4]-···-[x/2^31]


Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts