LeetCode Online Judge 题目C# 练习 - Divid Two Integer
Divide two integers without using multiplication, division and mod operator.
1 public static int Divid(int dividend, int divisor) 2 { 3 bool neg = false; 4 uint uint_dividend; 5 uint uint_divisor; 6 7 if (dividend < 0) 8 { 9 uint_dividend = (uint)~dividend + 1; // 等同于Convert.ToUInt32(dividend); 10 neg = !neg; 11 } 12 else 13 uint_dividend = (uint)dividend; 14 15 if (divisor < 0) 16 { 17 uint_divisor = (uint)~divisor + 1; 18 neg = !neg; 19 } 20 else 21 uint_divisor = (uint)divisor; 22 23 int quotient = 0; 24 25 while(uint_dividend > divisor) //每次被除数-除数,商++ 26 { 27 quotient++; 28 uint_dividend -= uint_divisor; 29 } 30 31 return neg ? -quotient : quotient; 32 }
代码分析:
这种方便比较笨,就是简单的一次一次循环被除数-除数,然后计算减了多少次,INT32.MaxValue / 1 就会让你哭了,虽然可以加以特殊条件,当除数 == 1,返回被除数,但是 INT32.MaxValue / 2 也够好受的。
1 public static int DividOpt(int dividend, int divisor) 2 { 3 bool neg = false; 4 uint uint_dividend; 5 uint uint_divisor; 6 7 if (dividend < 0) 8 { 9 uint_dividend = (uint)~dividend + 1; // 等同于Convert.ToUInt32(dividend); 10 neg = !neg; 11 } 12 else 13 uint_dividend = (uint)dividend; 14 15 if (divisor < 0) 16 { 17 uint_divisor = (uint)~divisor + 1; 18 neg = !neg; 19 } 20 else 21 uint_divisor = (uint)divisor; 22 23 uint ret = div(uint_dividend, uint_divisor); 24 25 if (neg) 26 return (int)~ret + 1; 27 28 return (int)ret; 29 } 30 31 public static uint div(uint dividend, uint divisor) 32 { 33 if (dividend < divisor) 34 return 0; 35 if (dividend == divisor) 36 return 1; 37 38 if (dividend > (divisor << 1) && (divisor << 1) > divisor) //如果divisor右移1位 < dividend 而且不溢出 39 { 40 uint temp = divisor << 1; 41 int bit_num = 1; //右移位数计数器 42 while (dividend > (temp << 1)) 43 { 44 bit_num++; 45 if ((temp << 1) > temp) //保证临时除数temp不溢出 46 temp <<= 1; 47 else 48 break; 49 } 50 51 return div(dividend - temp, divisor) + (uint)(1 << bit_num); // 例如(100 - 64 , 2) + 32, 32 = 64 / 2; } 53 else 54 return div(dividend - divisor, divisor) + 1; 55 }
代码分析:
这个优化版本利用了移位,让算法从O(dividen / divisor)提升到了O(lg(dividen / divisor))
主要算法是,循环做divisor << 1 到 > dividen之前的一个存到temp,然后递归 div( dividen - temp, divisor) + (1 << bit_num)