$\it{***方法一(己)***}$
思路:
若字符串为空,直接返回0;否则先过滤前面的空格,再进行判断,若第一个非空格字符不是正负号或者数字;或者第一个非空格字符是符号,但第二个字符非数字,则直接返回0;然后进行符号与整数记录,每多记录一位数都要判断一下是否超出边界,超出边界则直接返回预设值
要点:
1.用一个变量记录未添加当前位的整数值,若超最大数边界,则添加该位后数值比原来的数值要小而非更大
;若超最小数边界,则添加该位后数值比原来的数值要大而非更小
2.用一个bool变量记录符号,来对记录的整数进行不同的操作
3.$\it{优化:}$字符串为空/第一个非空格字符不是正负号或者数字/第一个非空格字符是符号但第二个字符非数字时,不用直接返回0,由于后续不进行操作,val值会保持为0,最后返回即可
代码:
#include<cmath>
class Solution {
public:
int strToInt(string str) {
int val=0; //记录当前遍历到的最长连续数字转换的整数
if(str.empty()) return 0;//字符串为空,返回0
int m=0; //第一个非空字符索引位置
while(str[m]==' ') m++;
if(str[m]!='+'&&str[m]!='-'&&(str[m]<'0'||str[m]>'9')) return 0;//该字符串中的第一个非空格字符不是一个有效整数字符或符号则返回0
if((str[m]=='+'||str[m]=='-')&&str.size()>=2&&(str[m+1]<'0'||str[m+1]>'9')) return 0;//该字符串第一个非空字符为符号,下一字符非数字则返回0
bool flag=true; //默认为正数
if(str[m]=='-')
{
flag=false;
m++;
}
else if(str[m]=='+') m++;
while(m<str.size()&&str[m]>='0'&&str[m]<='9')
{
int temp=val;
if(flag) val=str[m]-48+val*10;
else val=48-str[m]+val*10;
//判定是否超最大数边界
if(flag&&val<temp) return (int)pow(2,31)-1;
//判定是否超最小数边界
else if(!flag&&val>temp) return -(int)pow(2,31);
m++;
}
return val;
}
};
$\it{***方法二(y)***}$
思路:
先读取所有空格,然后判断非空格第一位是否为符号位,用整型变量minus标志符号,接着取紧随其后的整数字符,并以绝对值的形式用变量res记录,若记录的数大于$10^{11}$则直接跳出,否则直至取完紧挨其后的所有数字,然后乘以符号位还原,比较是否超出最大数/最小数范围,超出则重新调整res值,最后返回res值即可
要点:
1.由于正负可以根据读取的第一个非空格字符判断,采用一个整型变量作为符号标志
,以绝对值的形式读取整数字符即可
2.int型会爆范围,则用long long类型变量扩展范围来记录(不用考虑超范围补码表示问题)
(ps:返回值类型不一定非要是要求的返回值类型,只要实际的返回值类型精度
$\geqslant$要求返回值类型精度
即可)
3.注意行内代码注释写道:if(str[k++]==’-‘) minus=-1;会报错;判断语句的语句体只有在满足条件下执行
,但是判断语句的条件判断语句无论是否满足条件都一定执行
,所以这么写的话此处k一定会自增
4.在读取整数串时,超出$10^{11}$时就停止读取,直接出循环作判断。一方面,可以提高执行效率,$10^{10}$<int类型变量最大绝对值<$10^{11}$;另一方面,防止读取的整数过长,long long类型也会爆
代码:
class Solution {
public:
int strToInt(string str) {
int k=0;
int minus=1;//记录符号
long long res=0;//int会超范围,则直接使用long long
while(str[k]==' ') k++;
//if(str[k++]=='-') minus=-1;会报错
if(str[k]=='-')
{
minus=-1;
k++;
}
else if(str[k]=='+') k++;
while(k<str.size()&&str[k]>='0'&&str[k]<='9')
{
res=10*res+str[k]-48;//记录绝对值
if(res>1e11) break;
k++;
}
res*=minus;
if(res>INT_MAX) res=INT_MAX;
if(res<INT_MIN) res=INT_MIN;
return res;
}
};