1. 程式人生 > >一道簡單的演算法題--整數反轉的一些記錄

一道簡單的演算法題--整數反轉的一些記錄

首先是題幹

給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。
假設我們的環境只能儲存得下 32 位的有符號整數,則其數值範圍為 [−231, 231 − 1]。請根據這個假設,如果反轉後整數溢位那麼就返回 0。

我首先想到的就是字串的相關操作,於是頭也不回地寫出了以下的程式碼

public class Demo {
	public static int reverse(int x) {
		// 判斷是否溢位
		if (x < Integer.MAX_VALUE && x > Integer.MIN_VALUE) {
			// 轉化為字串,進行進一步操作
			String str = x + "";
			String newStr = "";
			// 判斷是否為負數
			if (x < 0) {
				str = str.substring(1, str.length());
				newStr = dofun(str);
				newStr = "-" + newStr;
			} else {
				newStr = dofun(str);
			}
			// 轉換回整形
			// 判斷反轉後是否超出範圍
			double test = Double.parseDouble(newStr);
			if (test > Integer.MAX_VALUE || test < Integer.MIN_VALUE) {
				return 0;
			}
			int result = Integer.parseInt(newStr);
			return result;
		}
		return 0;
	}

	public static String dofun(String str) {
		String newStr = "";
		// 置換
		for (int i = str.length(); i > 0; i--) {
			newStr += str.charAt(i - 1);
		}
		// 判斷最高位是否為0
		while (newStr.charAt(0) == 0) {
			// 是,無視該位
			newStr = newStr.substring(1, str.length());
		}
		return newStr;
	}

	public static void main(String[] args) {
		int result = reverse(1534236469);
		System.out.println(Integer.MAX_VALUE);
		System.out.println(result);
	}
}

長達50行的程式碼,雖然實現了功能,但也顯得過於繁瑣。其實,對於整數的反轉,只需要通過簡單的演算法知識便可解答。
對於每一位,我們可以通過

//reverse為輸入的數
x =  reverse%10;
reverse = reverse/10;

的迴圈,就可以得到每一位的數字,然後通過

result = rev * 10 + x;

便可得到反轉的資料,實際上,這是一個pop與push的過程。
不過,值得注意的是,result = rev * 10 + x是有可能溢位的。
如果rev == Integer.MAX_VALUE/10時,result就會溢位。
int型別的最大值為2147483647,也就是x>7。
而對於最小值2147483648,可知x<-8,綜上,寫出以下程式

class Demo02{
    public int reverse(int x) {
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
}

相比原來的程式碼簡單了很多。

學習演算法的道路依舊很長…