字符串轉成整數

原題

  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來求。

相關文章
相關標籤/搜索