面试题49:String to Integer (atoi)(Leetcode-8)

问题:将字符串转换成数字
分析:感觉题目不难,但是细节很多,容易想不到
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语句前,必须初始化所有用到的变量,否则编译不通过。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值