【剑指offer】把字符串转换成整数(C++)

题目描述

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

测试用例

输入str:输入一个字符串,包括数字字母符号,可以为空;
返回值int:合法的数值则返回该数字,否则返回0;
用例1:str="+2147483647"; 返回值2147483647。
用例1:str="-1a33"; 返回值0。

解决方案

正数情况下,当前值为res,待加入数字字符为c,则新的res = 10res + (c-‘0’);
正负号问题
首字符可能是 ‘+’ ‘-’,需要在遍历数字之前进行判断;
采用flag标明正负,在程序结束时返回符号正确的数值。
数值越界问题
针对int型数字上下界 [232, 232-1],我们默认使用负数来表示累加和(使用正数会漏掉INT_MIN),则 res = 10
res-(c-‘0’);并用负的limit来表示最值,正负数的limit分别是 {-INT_MAX, INT_MIN} ;
在判断数值是否越界时,应保证 10 * res - (c-‘0’) >= limit ;为保证不出现越界,需要(1)先判断 10 * res 是否越界,由 10*res >= limit 得到判定条件 res >= limit/10;(2)当满足条件1后,再判断res加上个位数后是否越界,即 limit - 10 * res <= -(c-‘0’);两个条件依次满足后才能保证数字的正确性;否则均判定为非法数字,直接返回0。

class Solution {
public:
    //用负数表示累加值
    int StrToInt(string str) {
        if(str.empty()) return 0;
        //为避免出现res不能存储int_min的情况,将res设为负值进行累加
        //flag用于标记正负,-1表示正(最后返回flag*res)
        int res = 0, idx = 0, flag = -1;
        //limit表示数值界限,正数界-INT_MAX,负数界INT_MIN
        int limit = numeric_limits<int>::min() + 1;
        //首先判断首位字符有没有'+''-'号,并据此调整flag和limit
        if(str.at(idx)=='+' || str.at(idx)=='-'){
            flag = str.at(idx)=='+'? -1 : 1;
            limit -= str.at(idx)=='+'? 0 : 1;
            ++idx;
        }
        int temp;
        //数字字符逐位相加
        for(idx; idx<str.size(); ++idx){
            if(str.at(idx)<'0' || str.at(idx)>'9') return 0;
            temp = str.at(idx)-'0';
            //基本条件,在负数下res要大于等于int_max/10,再去判断加上个位数的情况
            if(limit/10 <= res){
                //再判断加上个位数后是否越界,limit <= res*10 - temp
                //即limit-res*10 <= -temp
                if(limit-res*10 <= -temp){
                    res = res*10 - temp;
                }
                //越界返回最大值
                else{
                    return flag * limit;
                }
            }
            else{
                return 0;
            }
        }
        return flag*res;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值