Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.html
實現一個atoi函數,將字符串轉成整形
要點:考慮全部的輸入狀況。git
前導字符是+或-或者沒有,接下來輸入的是數字,數字不能整數能表示的最大或最小數。若是超過就返回對應的最小或者最小的值。ide
public class Solution { public int atoi(String str) { if (str == null || str.length() == 0) { // throw new NumberFormatException("Invalid input string: " + str); return 0; } // 若是字符串以空格開始 int start = 0; //從開始找第一個不是空格的數 boolean positive = true; // 是否爲正數默認爲true if (str.charAt(start) == ' ') { while (str.charAt(start) == ' ') { start++; if (start >= str.length()) { // 輸入的全是空格 // throw new NumberFormatException("Invalid input string: " + str); return 0; } } } if (str.charAt(start) == '-') { // 第一個非空白字符中- positive = false; start++; } else if (str.charAt(start) == '+') {// 第一個非空白字符是+ start++; } else if (str.charAt(start) >= '0' && str.charAt(start) <= '9') { // 第一個非空白字符是數字 return cal(str, start, true); } else { // 其它狀況就拋出異常 // throw new NumberFormatException("Invalid input string: " + str); return 0; } if (start >= str.length()) { // 第一個非空白字符是+或者-但也是最後一個字符 // throw new NumberFormatException("Invalid input string: " + str); return 0; } if (str.charAt(start) > '9' || str.charAt(start) < '0') { // +或者-後面接的不是數字 // throw new NumberFormatException("Invalid input string: " + str); return 0; } else { return cal(str, start, positive); } } private int cal(String str, int start, boolean positive) { long result = 0; while (start < str.length() && str.charAt(start) >= '0' && str.charAt(start) <= '9') { result = result * 10 + (str.charAt(start) - '0'); if (positive) { // 若是是正數 if (result > Integer.MAX_VALUE) { // throw new NumberFormatException("Invalid input string: " + str); return Integer.MAX_VALUE; } } else { if (-result < Integer.MIN_VALUE) { // throw new NumberFormatException("Invalid input string: " + str); return Integer.MIN_VALUE; } } start++; } if (positive) { return (int) result; } else { return (int) -result; } } }
一、如何將字符串String轉化爲整數int
int i = Integer.parseInt(str);
int i = Integer.valueOf(my_str).intValue();
注: 字串轉成Double, Float, Long的方法大同小異。
二、如何將字符串String轉化爲Integer
Integer integer=Integer.valueOf(i)
三、如何將整數 int 轉換成字串 String?
答:有三種方法:
String s = String.valueOf(i);
String s = Integer.toString(i);
String s = "" + i;
注:Double, Float, Long 轉成字串的方法大同小異。
四、如何將整數int轉化爲Integer
Integer integer=new Integer(i)
五、如何將Integer轉化爲字符串String
Integer integer=String()
六、如何將Integer轉化爲int
int num=Integer.intValue()
七、如何將String轉化爲BigDecimal
BigDecimal d_id=new BigDecimal(str)函數
一、思路及注意事項ui
參考: http://blog.sina.com.cn/s/blog_514c89a90100d7qh.htmlthis
歸納起來有幾種狀況spa
1)字符串開頭是「+」號或「-」號的處理code
2)非法字符的判斷(不是數字)orm
3)整數溢出問題。htm
看看Java函數庫中的Integer.parseInt(String sting)的源碼如何處理這些問題的。
/** * Parses the specified string as a signed decimal integer value. The ASCII * character \u002d ('-') is recognized as the minus sign. * * @param string * the string representation of an integer value. * @return the primitive integer value represented by {@code string}. * @throws NumberFormatException * if {@code string} cannot be parsed as an integer value. */ public static int parseInt(String string) throws NumberFormatException { return parseInt(string, 10); } /** * Parses the specified string as a signed integer value using the specified * radix. The ASCII character \u002d ('-') is recognized as the minus sign. * * @param string * the string representation of an integer value. * @param radix * the radix to use when parsing. * @return the primitive integer value represented by {@code string} using * {@code radix}. * @throws NumberFormatException * if {@code string} cannot be parsed as an integer value, * or {@code radix < Character.MIN_RADIX || * radix > Character.MAX_RADIX}. */ public static int parseInt(String string, int radix) throws NumberFormatException { if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { throw new NumberFormatException("Invalid radix: " + radix); } if (string == null) { throw invalidInt(string); } int length = string.length(), i = 0; if (length == 0) { throw invalidInt(string); } boolean negative = string.charAt(i) == '-'; if (negative && ++i == length) { throw invalidInt(string); } return parse(string, i, radix, negative); } private static int parse(String string, int offset, int radix, boolean negative) throws NumberFormatException { int max = Integer.MIN_VALUE / radix; int result = 0, length = string.length(); while (offset < length) { int digit = Character.digit(string.charAt(offset++), radix); if (digit == -1) { throw invalidInt(string); } if (max > result) { throw invalidInt(string); } int next = result * radix - digit; if (next > result) { throw invalidInt(string); } result = next; } if (!negative) { result = -result; if (result < 0) { throw invalidInt(string); } } return result; }
parseInt(String string, int radix)判斷了
1) radix進制超出範圍 ( Character. MIN_RADIX = 2, Character. MAX_RADIX )=36)
2)字符串爲null
3)字符串長度爲空
4)字符串第一位爲「-」且只有一位
沒有異常以後進行 parse(String string, int offset, int radix, boolean negative) 判斷,參數即字符串,偏移量,進制, negative (若是開頭沒有「-」則offset=0,negative=false,不然爲offset=1,neagtive=true)
在 parse(String string, int offset, int radix, boolean negative)主要進行了溢出的判斷。利用 offset++來控制移動, 在 while (offset < length) 循環中 直到倒數 第二位的時候,若是已經 小於 max = Integer.MIN_VALUE / radix 的話代表必定會溢出。例如"-2147483648"
倒數第二位的時候 :result= -214748364,max = -214748364,max>result不成立代表 能夠進行最後一位的處理。
這裏爲何不先求得當前的結果再同 Integer.MIN_VALUE比較?而是先同 Integer.MIN_VALUE / radix比較再決定是否進行下一位的添加? 不言而喻。
二、參考源碼實
現字符串轉化爲整數
能夠對比 http://zhedahht.blog.163.com/blog/static/25411174200731139971/ 。
public class StringToIntTest { /** * @author 曹豔豐 北京大學 */ public static void main(String[] args) { // TODO 自動生成的方法存根 try { System.out.println(parseInt("cao21'''474fefda8364fe7")); System.out.println(parseInt("-2147483648")); System.out.println(parseInt("-2147483651")); System.out.println(parseInt("-2147483648")); System.out.println(parseInt("-21474836410")); } catch (MyException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } } private static int parseInt(String string) throws MyException { /* 異常狀況1:字符串爲null */ if (string == null) { throw new MyException("字符串爲null!"); } int length = string.length(), offset = 0; /* 異常狀況2:字符串長度爲0 */ if (length == 0) { throw new MyException("字符串長度爲0!"); } boolean negative = string.charAt(offset) == '-'; /* 異常狀況3:字符串爲'-' */ if (negative && ++offset == length) { throw new MyException("字符串爲:'-'!"); } int result = 0; char[] temp = string.toCharArray(); while (offset < length) { char digit = temp[offset++]; if (digit <= '9' && digit >= '0') { int currentDigit = digit - '0'; /* * 異常狀況4:已經等於Integer.MAX_VALUE / 10,判斷要添加的最後一位的狀況: * 若是是負數的話,最後一位最大是8 若是是正數的話最後一位最大是7 */ if (result == Integer.MAX_VALUE / 10) { if ((negative == false && currentDigit > 7) || (negative && currentDigit > 8)) { throw new MyException("溢出!"); } /* * 異常狀況5:已經大於Integer.MAX_VALUE / 10 * 不管最後一位是什麼都會超過Integer.MAX_VALUE */ } else if (result > Integer.MAX_VALUE / 10) { throw new MyException("溢出!"); } int next = result * 10 + currentDigit; result = next; } } if (negative) { result = -result; } return result; } } /* 自定義異常 */ class MyException extends Exception { /** * */ private static final long serialVersionUID = 1749149488419303367L; String message; public MyException(String message) { // TODO 自動生成的構造函數存根 this.message = message; } @Override public String getMessage() { // TODO 自動生成的方法存根 return message; } }
****************************
「若是是負數的話,最後一位最大是8 若是是正數的話最後一位最大是7」能夠用Integer.MIN_VALUE%10和 Integer.MAX_VALUE%10來求。