Leetcode link.
Q: Divide two integers without using multiplication, division and mod operator.
A:
I managed to crack it by myself the first time I fought through leetcode, but not this time. I had to go back and check what I had done. :( shame
The idea is simple. Shifting operation is your friend. Test case 70051: 700=23⋅51+292292=22⋅51+8888=20⋅51+37
We stop at 37 because 37<51.
All right that's it. Answer is 23+22+20=13.
Corner cases' time!
- Dividend / Divisor == 0?
- Dividient or Divisor is negative? or both are negative?
- This is about integer, so what do you consider? Overflow! Dividend/divisor==INT_MIN/INT_MAX or −INT_MIN/−INT_MAX?
Second one is tricky to handle. Judge the sign! Then use abs function to do it! Yeah, you'll see there is one loose end soon...
Third one? I cheated... I used long long type to handle everything. If I don't, the loose end in second question will reveal: The devil abs(INT_MIN) ! ideone says abs(INT_MIN)==INT_MIN, someone on leetcode forum reports abs(−2147483647)=−2147483644 or something like that. Anyway, I cheated...
My code is as follow. Not the best code though. Feel free to play it here.
pair<long long, long long> decompose(long long a, long long b) { // DONT MAKE a < b int k = 0; // decompose a/b = 2^k + d, d < 2^k while (b < a) { b <<= 1; k++; } if (b == a) return make_pair(k, 0); return make_pair(--k, a - (b>>1)); } int divide(int dvd, int dvs) { if (dvs == 0) throw overflow_error("Divide by zero exception"); if (dvd == 0) return 0; long long ldvd, ldvs; ldvd = abs((long long)dvd); ldvs = abs((long long)dvs); if (ldvd < ldvs) return 0; long long ret = 0; pair<long long, long long> kb; do{ kb = decompose(ldvd, ldvs); ret += 1 << kb.first; ldvd = kb.second; } while (kb.second >= ldvs); return ((dvd>>31) == (dvs>>31)) ? ret : (~ret + 1); }
No comments:
Post a Comment