题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入一个字符串,包括数字字母符号,可以为空
返回值描述:
如果是合法的数值表达则返回该数字,否则返回0
思路
首先考虑不合法的输入:
1.含有除正负符号外的非数字
2.多个正负符号
3.只有一个正负符号,但是不在字符串头部
先看我的第一次实现:
class Solution {
public:
int StrToInt(string str) {
if (str.length() == 0)
return 0;
queue<int> q;
queue<char> cq0;
queue<char> cq1;
for (int i = 0; i < str.length(); i++)
{
char s = str[i];
switch (s)
{
case '+':
cq0.push('+'); break;
case '-':
cq1.push('-'); break;//最后不空就取相反数
case'0':
q.push(0); break;
case'1':
q.push(1); break;
case'2':
q.push(2); break;
case'3':
q.push(3); break;
case'4':
q.push(4); break;
case'5':
q.push(5); break;
case'6':
q.push(6); break;
case'7':
q.push(7); break;
case'8':
q.push(8); break;
case'9':
q.push(9); break;
default:
return 0;//除这些字符外都返回false
}
}
if (cq0.size() > 1 || cq1.size() > 1)//多于1个正负就返回false
return 0;
if ((!cq0.empty()) && (!cq1.empty()))//同时有正负号返回false
return 0;
int ret=0;
for (int i = q.size() - 1; i >= 0; i--)
{
ret += q.front() * pow(10,i);
q.pop();
}
if (!cq1.empty())//判断返回类型
return ret * (-1);
else
return ret;
}
};
这个代码是能够通过牛客的测试,但是有明显的问题——如果有且仅有一个正负号且出现在字符串中间的时候,是非法输入,但是也能输出值来。
思考:
在写的过程中,又要判断第一个是正负还是数字还是其他符号,ifelse写得很糟心;
为了检测数字是什么,要写10个case,很麻烦,看了大佬得实现,自己写出了下面得代码:
正确的实现:
class Solution {
public:
int StrToInt(string str) {
if (str.length()==0) return 0;
const int length=str.length();
int i=0;
while (i<length&&str[i]==' ') //排除前面得空格(虽然不排判false也行)
i++;
if (i==length) return 0;//如果这时已经到头了,说明全是空格,返回false
if (!isdigit(str[i])&&str[i]!='-'&&str[i]!='+') return 0;//如果第一个有效字符不是数字或者正负直接返回false
//这里得isdigit()函数检测字符是不是对应的数字
bool is_negtive=str[i]=='-'?true:false;//正负标志位
i=isdigit(str[i])?i:i+1;//再检测是不是数字,不是的话就要后移一位开始
long long ans=0;//防止输出大于INT_MAX的值
while (i<length&&isdigit(str[i]))//小于长度且为数字才进入循环
{
ans=ans*10+(str[i]-'0');
//这个处理很精髓,用str[i]对应的ASCII码减去‘0’对应的码就得到了str[i]对应的数字
i++;
if (!is_negtive&&ans>INT_MAX)//正数且大于INT_MAX返回false,因为超界了
return 0;
if (is_negtive&&ans>1L+INT_MAX)//超过最小负数也返回false
return 0;
}
if (i!=length) return 0;//没有到头说明中间出现了非数字导致没有进入上面的while循环
return is_negtive?(-ans):ans;
}
};