題目簡析:實現 字符-àint整數的轉換,題意很簡單,實現方法也是多種多樣,掃描整個字符串、用棧、隊列都是可以的,不過這題的要點其實不是把字符換成整數這一步,而是對於一些非法輸入等情況的處理。
輸入接受一個字符串,根據一些提交測試來看,接受的字符串可能的情況,是包括0個及以上的正負號、空格、數字以及其他非法符號的隨意排列組合,下面列舉一些例子
“ ”
“123”
“ 123”
“ 123 ”
“ 1 23 ”
“-123 ”
“ -123 ”
“+ 123 ”
“ +12 3 ”
“+-134 ”
“+ +123 ”
“ 123+ + 12 ”
“&%124”
根據一些非法字符串總結出來,合法字符串應該包括以下條件:
(1)數字串前面允許0個,或1個+或-號,不允許連續正負號或者正負號以外的其他符號(如連續的+-號,%&@*/等符號)
(2)數字與數字間有任何及任意數量非數字字符都是非法的,非數字字符前面的數字串若合法則輸出,但非數字字符後面的數字串無論合法非法,均不輸出(如“124 45”或“124%&45”輸出124,但“&&1234 54”屬於非法數字串)
(3)正負號與數字之間不能有空格,但是在帶符號數字串的正負號前面、或者無符號的數字串前面可以有空格
(4)數字範圍要在int範圍(-2147483648~2147483647)內,假如超出範圍,只輸出最大or最小值
(如:“3333333333333333”—>2147483647 “-333333333333333” —>-2147483648 )
(5)不能爲空字符串、或僅有符號的字符串
(6)支持整數,故小數點也屬於非法字符,參考第2點。
對於以上要求,除了超出數字範圍的第四點以外,其他數字串若非法則輸出數字0,否則輸出對應的數字(int類型)
字符串轉換思路:
經過對合法字符串要求的總結分析,在進行轉換之前,首先應該排除非法字符串,以及對字符串進行提取的預處理,因爲從第三點看來,並不是字符串所有的數字都是需要轉換的。
第一步在字符串首端的檢查上,簡單排除0長度字符串、1長度無數字字符串。
第二步是對空格的處理,根據第2、3點,我們可以總結爲——在遇到任何非空字符前,空字符都是可以忽略的,但是遇到非空字符後,任何空字符都屬於非法字符,與其他非數字字符都可以立即判定字符串非法。因此對字符串進行解析之前,我們要跳過前端的空格。
第三步是找到一個合法的數字串並截取,根據第1點看是否可能存在一個合法的數字串開端,若有則截取至第一個非法字符(第2點),將之保存(棧或者隊列或者用變量記錄位置均可)。
第四步是將之轉化爲數字,我用的方法是將每一位進行冪運算並累加(sum+=bit*pow,pow是1、10、100……1000000000),並判斷正負號情況。
最後一步是處理溢出問題,對於int範圍而言,採取累加的方法是有可能導致溢出的。這裏判斷的方法因人而異,我的方法是判斷累加過程是否產生正負變化(我是先累加完才賦予正負,因此累加的結果必定是整數),以及待累加的冪的大小(int範圍是-2147483648~2147483647,因此超過1000000000這個數量級的待累加冪意味着溢出要發生),這個方法僅供參考。
其他的一些細節比如溢出後值的輸出,稍微有點取巧的地方,其實用簡單的if else也能解決,不一定要像我那樣偷懶。
下面就附上代碼吧
class Solution {
public:
int myAtoi(string str) {
int pow=1;
int sum=0;
stack<int> stk;
int flag=1;
bool overflow=false;
if(str.length()==0)
return 0;
else if(str.length()==1)
return (str[0]>='0' && str[0]<='9')*(str[0]-'0');
int blank=0;
while(1){
if(str[blank]==' ')
blank++;
else
break;
}
int i=(str[blank]=='+' || str[blank]=='-')+blank;
while(i<str.length()){
if(str[i]>='0' && str[i]<='9')
stk.push(str[i]-'0');
else
break;
i++;
}
while(!stk.empty()){
sum=sum+stk.top()*pow;
if(sum<0 || pow > 1000000000){
sum=2147483647;
overflow=true;
break;
}
pow*=10;
stk.pop();
}
if(str[blank]=='-')
flag=-1;
if(overflow)
return flag*sum+(flag-overflow)/2;
else
return flag*sum;
}
};
Submission Result: Accepted
Runtime: 0 ms
題目鏈接:https://leetcode.com/problems/string-to-integer-atoi/description/