剑指offer49--将字符串转化成数字

题目描述

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为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;
        
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值