算法第五週作業01

Description

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

Solution

 假定計算10 / 3,其中left = 10, right = 3,使用<<1 平移操作代替乘2運算,進而代替乘法運算。
1. 首先讓10與3(即right<<0)比較,由於10>3,則繼續下輪;
    讓10與6 (right<<1)比較,由於10>6,則繼續下輪;
讓10與12(right<<2)比較,由於10<12,那麼選擇上輪結果2(2是這輪 10/3 的子結果)。
2. 讓4(10-6)與3比較,由於4>3,則繼續下輪;
讓4(10-6)與6比較,由於4<6,那麼選擇上輪結果1(1是這輪 4/3 的子結果)。
3. 讓1(4-3)與3比較,由於首輪中1<4,那麼此次運算子結果爲0(0時1/3的子結果)。
4. 綜上,10/3 的結果爲2+1+0, 餘數爲1%3 = 1.
ps: 代碼中考慮到了數值溢出問題,所以將其轉爲long類型,並判斷溢出情況,JAVA中int範圍-2147483648 ~ 2147483647

Code

public int divide(int dividend, int divisor) {
		if (divisor == 0) {
			return Integer.MAX_VALUE;
		}
		// 轉爲long類型,方便識別溢出
		long left = dividend > 0 ? dividend : -(long) dividend;
		long right = divisor > 0 ? divisor : -(long) divisor;
		long result = 0;
		while (true) {
			long subRes = 0;
			long div = right;
			// 分別跟divisor的1倍、2倍、4倍...比較
			while (div <= left) {
				if(subRes == 0){
					subRes = 1;
				} else {
					subRes = subRes << 1;
				}
				div = div << 1;
			}
			if (div == left) {
				// 如果左值恰好是divisor的2^n倍
				result += subRes;
				break;
			} else if(subRes == 0){
				// 如果左值比右值還小,則直接退出
				break;
			} else {
				// 計算剩餘部分,賦予左值
				result += subRes;
				left -= div>>1;

			}
		}
		// 符號和溢出判斷
		if (dividend < 0 && divisor > 0 || dividend > 0 && divisor < 0) {
			return -(int) result;
		} else if (result > Integer.MAX_VALUE) {
			return Integer.MAX_VALUE;
		} else {
			return (int) result;
		}
	}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章