问题:将字符串转换成数字
分析:感觉题目不难,但是细节很多,容易想不到
1.数字首尾有空格 如s=“ 123456 ”
2.数字前出现了不必要或多于的字符导致数字认证错误,输出0 如s=“ b1234” ,s=“ ++1233” , s=“ +-1121”
3.数字中出现了不必要的字符,返回字符前的数字 如s=“ 12a12” , s=“ 123 123”,则输出12,123。(按照C语言的标准是把异常字符起的后面全部截去,保留前面的部分作为结果)
分析:感觉题目不难,但是细节很多,容易想不到
1.数字首尾有空格 如s=“ 123456 ”
2.数字前出现了不必要或多于的字符导致数字认证错误,输出0 如s=“ b1234” ,s=“ ++1233” , s=“ +-1121”
3.数字中出现了不必要的字符,返回字符前的数字 如s=“ 12a12” , s=“ 123 123”,则输出12,123。(按照C语言的标准是把异常字符起的后面全部截去,保留前面的部分作为结果)
4.数字越界 超过了范围(-2147483648--2147483647) 若超过了负数的 输出-2147483648 超过了正数的输出2147483647
Java版本:
public int atoi(String str) {
str = str.trim();
if (str == null || str.length()==0) {
return 0;
}
long result = 0,test=0;
boolean negative = false;
int i = 0, len = str.length();
int digit,ret;
char firstChar = str.charAt(0);
if (firstChar == '-') {
negative = true;
i++;
} else if (firstChar == '+'){
i++;
}
while (i < len) {
digit = str.charAt(i++)-'0';
if (digit < 0 || digit > 9) {
ret = (int)result;
return negative ? -ret : ret;
}
result = result*10+digit;
test = negative ? -result : result;
if( test > Integer.MAX_VALUE){
return Integer.MAX_VALUE;
}
if(test < Integer.MIN_VALUE){
return Integer.MIN_VALUE;
}
}
ret = (int)result;
return negative ? -ret : ret;
}
另外,补充一个知识点:
int i=Integer.MIN_VALUE-1,则i=Integer.MAX_VALUE;
i=Integer.MAX_VALUE+1,则i=Integer.MIN_VALUE;
这两种情况下编译器都不会报错,超过了Integer范围,则会循环从头开始。
C++版本(未用long判断溢出):
int myAtoi(string str) {
int len = str.length();
if(len<1)return 0;
bool is_positive = true;
char c = str.at(0);
int i=0;
while(c==' '){
i++;
c=str.at(i);
}
if( c == '-'){
is_positive = false;
i++;
}else if(c == '+'){
i++;
}else if(c<'0' || c>'9'){
return 0;
}
int ret=0;
int a=0;
while(i<len){
a = str.at(i)-'0';
if(a <0 || a>9){
break;
}
//检查是否溢出
if(ret > (INT_MAX-a)/10){
return is_positive?INT_MAX:INT_MIN;
}
ret = ret*10 + a;
i++;
}
return is_positive?ret:-ret;
}
思路与上相同,先trim字符串,C++中没有trim函数,只有遍历。
不同的是,这次没有用long类型检查是否溢出,而是判断 ret > (INT_MAX-a)/10 是否溢出。
因为:如果ret*10+a>INT_MAX,那么解不等式可以得到上述判断条件。
九度平台:
该平台下只要出现非法字符,都输出My God,其他与leetcode要求一样。
#include <iostream>
#include <limits.h>
using namespace std;
void myAtoi(string str)
{
int len = str.length();
int ret=0,a=0,i=0;
bool is_positive = true;
char c = '\0';
if(len<1)goto __invalid;
c = str.at(0);
while(c==' '){
i++;
c=str.at(i);
}
if( c == '-'){
is_positive = false;
i++;
}else if(c == '+'){
i++;
}else if(c<'0' || c>'9'){
goto __invalid;
}
while(i<len){
a = str.at(i)-'0';
if(a <0 || a>9){
goto __invalid;
}
//检查是否溢出
if(ret > (INT_MAX-a)/10){
cout<<(is_positive?INT_MAX:INT_MIN)<<endl;
}
ret = ret*10 + a;
i++;
}
cout<<(is_positive?ret:-ret)<<endl;
return;
__invalid:
cout<<"My God"<<endl;
return;
}
int main()
{
string str;
while(cin>>str){
myAtoi(str);
}
return 0;
}
代码用了goto语句,特别注意的是:
在第一次调用goto语句前,必须初始化所有用到的变量,否则编译不通过。