String to Integer

Question

  1. Implement function atoi to convert a string to an integer.
  2. If no valid conversion could be performed, a zero value is returned.
  3. If the correct value is out of the range of representable values,
  4. INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.
  5. Example
  6. "10" => 10
  7. "-1" => -1
  8. "123123123123123" => 2147483647
  9. "1.0" => 1

題解

經典的字符串轉整數題,邊界條件比較多,比如是否需要考慮小數點,空白及非法字符的處理,正負號的處理,科學計數法等。最先處理的是空白字符,然後是正負號,接下來只要出現非法字符(包含正負號,小數點等,無需對這兩類單獨處理)即退出,否則按照正負號的整數進位加法處理。

Java

  1. public class Solution {
  2. /**
  3. * @param str: A string
  4. * @return An integer
  5. */
  6. public int atoi(String str) {
  7. if (str == null || str.length() == 0) return 0;
  8. // trim left and right spaces
  9. String strTrim = str.trim();
  10. int len = strTrim.length();
  11. // sign symbol for positive and negative
  12. int sign = 1;
  13. // index for iteration
  14. int i = 0;
  15. if (strTrim.charAt(i) == '+') {
  16. i++;
  17. } else if (strTrim.charAt(i) == '-') {
  18. sign = -1;
  19. i++;
  20. }
  21. // store the result as long to avoid overflow
  22. long result = 0;
  23. while (i < len) {
  24. if (strTrim.charAt(i) < '0' || strTrim.charAt(i) > '9') {
  25. break;
  26. }
  27. result = 10 * result + sign * (strTrim.charAt(i) - '0');
  28. // overflow
  29. if (result > Integer.MAX_VALUE) {
  30. return Integer.MAX_VALUE;
  31. } else if (result < Integer.MIN_VALUE) {
  32. return Integer.MIN_VALUE;
  33. }
  34. i++;
  35. }
  36. return (int)result;
  37. }
  38. }

源碼分析

符號位使用整數型表示,便於後期相乘相加。在 while 循環中需要注意判斷是否已經溢位,如果放在 while 循環外面則有可能超過 long 型範圍。

C++

  1. class Solution {
  2. public:
  3. bool overflow(string str, string help){
  4. if(str.size() > help.size()) return true;
  5. else if(str.size() < help.size()) return false;
  6. for(int i = 0; i < str.size(); i++){
  7. if(str[i] > help[i]) return true;
  8. else if(str[i] < help[i]) return false;
  9. }
  10. return false;
  11. }
  12. int myAtoi(string str) {
  13. // ans: number, sign: +1 or -1
  14. int ans = 0;
  15. int sign = 1;
  16. int i = 0;
  17. int N = str.size();
  18. // eliminate spaces
  19. while(i < N){
  20. if(isspace(str[i]))
  21. i++;
  22. else
  23. break;
  24. }
  25. // if the whole string contains only spaces, return
  26. if(i == N) return ans;
  27. if(str[i] == '+')
  28. i++;
  29. else if(str[i] == '-'){
  30. sign = -1;
  31. i++;
  32. }
  33. // "help" gets the string of valid numbers
  34. string help;
  35. while(i < N){
  36. if('0' <= str[i] and str[i] <= '9')
  37. help += str[i++];
  38. else
  39. break;
  40. }
  41. const string maxINT = "2147483647";
  42. const string minINT = "2147483648";
  43. // test whether overflow, test only number parts with both signs
  44. if(sign == 1){
  45. if(overflow(help, maxINT)) return INT_MAX;
  46. }
  47. else{
  48. if(overflow(help, minINT)) return INT_MIN;
  49. }
  50. for(int j=0; j<help.size(); j++){
  51. ans = 10 * ans + int(help[j] - '0');
  52. }
  53. return ans*sign;
  54. }
  55. };

源碼分析

C++解法並沒有假設任何內建的string演算法,因此也適合使用在純C語言的字元陣列上,此外溢位的判斷直接使用字串用一個輔助函數比大小,這樣如果面試官要求改成string to long 也有辦法應付,不過此方法會變成machine-dependent,嚴格來說還需要寫一個輔助小函數把INT_MAXINT_MIN轉換成字串來使用,這邊就先省略了,有興趣的同學可以自己嘗試練習。

複雜度分析

Reference