【劍指Offer學習】【面試題49:把字串轉換成整數】
阿新 • • 發佈:2019-01-10
題目:實現一個函式stringToInt,實現把字串轉換成整數這個功能,不能使用atoi或者其他類似的庫函式。
題目解析
這看起來是很簡單的題目,實現基本功能 ,大部分人都能用10行之內的程式碼解決。可是,當我們要把很多特殊情況即測試用例都考慮進去,卻不是件容易的事。解決數值轉換問題本身並不難,但我希望在寫轉換數值的程式碼之前,應聘者至少能把空指標,空字串”“,正負號,溢位等方方面面的測試用例都考慮到,並且在寫程式碼的時候對這些特殊的輸入都定義好合理的輸出。當然,這些輸出並不一定要和atoi完全保持一致,但必須要有顯式的說明,和麵試官溝通好。
這個應聘者最大的問題就是還沒有養成在寫程式碼之前考慮所有可能的測試用例的習慣,邏輯不夠嚴謹,因此一開始的程式碼只處理了最基本的數值轉換。後來我每次提醒他一處特殊的測試用例之後,他改一處程式碼。儘管他已經做了兩次修改,但仍然有不少很明顯的漏洞,特殊輸入空字串”“,邊界條件比如最大的正整數與最小的負整數等。由於這道題思路本身不難,因此我希望他把問題考慮得極可能周到,程式碼儘量寫完整。
程式碼實現
public class Test49 {
/**
* 題目:實現一個函式stringToInt,實現把字串轉換成整數這個功能,
* 不能使用atoi或者其他類似的庫函式。
*
* @param num
* @return
*/
public static int stringToInt(String num) {
if (num == null || num.length() < 1) {
throw new NumberFormatException(num);
}
char first = num.charAt(0);
if (first == '-') {
return parseString(num, 1, false);
} else if (first == '+') {
return parseString(num, 1, true);
} else if (first <= '9' && first >= '0') {
return parseString(num, 0, true);
} else {
throw new NumberFormatException(num);
}
}
/**
* 判斷字元是否是數字
*
* @param c 字元
* @return true是,false否
*/
private static boolean isDigit(char c) {
return c >= '0' && c <= '9';
}
/**
* 對字串進行解析
*
* @param num 數字串
* @param index 開始解析的索引
* @param positive 是正數還是負數
* @return 返回結果
*/
private static int parseString(String num, int index, boolean positive) {
if (index >= num.length()) {
throw new NumberFormatException(num);
}
int result;
long tmp = 0;
while (index < num.length() && isDigit(num.charAt(index))) {
tmp = tmp * 10 + num.charAt(index) - '0';
// 保證求的得的值不超出整數的最大絕對值
if (tmp > 0x8000_0000L) {
throw new NumberFormatException(num);
}
index++;
}
if (positive) {
if (tmp >= 0x8000_0000L) {
throw new NumberFormatException(num);
} else {
result = (int) tmp;
}
} else {
if (tmp == 0x8000_0000L) {
result = 0x8000_0000;
} else {
result = (int) -tmp;
}
}
return result;
}
public static void main(String[] args) {
// System.out.println(Integer.parseInt(Integer.MIN_VALUE + ""));
// System.out.println(0x8000_0000L);
// System.out.println(stringToInt(""));
System.out.println(stringToInt("123"));
System.out.println(stringToInt("+123"));
System.out.println(stringToInt("-123"));
System.out.println(stringToInt("1a123"));
System.out.println(stringToInt("+2147483647"));
System.out.println(stringToInt("-2147483647"));
System.out.println(stringToInt("+2147483648"));
System.out.println(stringToInt("-2147483648"));
// System.out.println(stringToInt("+2147483649"));
// System.out.println(stringToInt("-2147483649"));
// System.out.println(stringToInt("+"));
// System.out.println(stringToInt("-"));
}
}