剑指Offer--049-把字符串转换成整数

链接


牛客OJ:把字符串转换成整数

九度OJ:http://ac.jobdu.com/problem.php?pid=1508

GitHub代码: 049-把字符串转换成整数

CSDN题解:剑指Offer–049-把字符串转换成整数

牛客OJ九度OJCSDN题解GitHub代码
049-把字符串转换成整数1508-把字符串转换成整数剑指Offer–049-把字符串转换成整数049-把字符串转换成整数

相同题目 LeetCode题解–8. String to Integer (atoi)

题意


题目描述

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。

样例输入

1a33

-2147483648

样例输出

0

-2147483648

分析


同样的题目在LeetCode上

相同题目 LeetCode题解–8. String to Integer (atoi)

简单问题,如下代码即是主要框架

for (; *str != '\0'; str++)
{

    if ('0' <= *str && *str <= '9')
    {
        value *= 10;
        value += *str - '0';
#ifdef DEBUG
        printf("value = %lld\n", value);
#endif
    }
    else
    {
        break;
    }
}

但是需要注意的问题,

  • 前面的空白字符
//  排除前导的空格
while (*str == ' '  || *str == '\n' || *str == '\t')          //  排除前导的空格
{
    str++;
}
  • 数字前面可能有符号位+/-
//  判断符号位+ -
if (*str == '+')
{
    str++;
}
else if (*str == '-')
{
    str++;
    minus = true;
}
  • overflow问题

我的解决方案是在循环的过程中,只要一发生溢出就结束

//  解决OVER_FLOW的问题
//  INT_MAX     2147483647
//  INT_MIN     -2147483648  minus = true
if((minus == true  && value > (unsigned long)(INT_MAX) + 1)     //  负数绝对值最大为INT_MAX + 1
 || (minus == false && value > INT_MAX))                         //  正数最大值为INT_MAX
{
    debug <<value <<", " <<INT_MAX + 1 <<endl;
    debug <<"to max than int" <<endl;
    break;
 }

如果最后再判断可能出现的问题,因为不管我们value用什么保存,long,long long,他们都有表示范围,都存在溢出,字符串过长时都会溢出,溢出后可能会发生截断,或者甚至读取成一个负数,那么我们循环结束后再判断就不可行。

分析的已经很好了,我们直接上代码吧

#include <iostream>
using namespace std;


//  调试开关
#define __tmain main

#ifdef __tmain

#define debug cout

#else

#define debug 0 && cout

#endif // __tmain

class Solution
{
public:
    int StrToInt(string str)
    {
        string::iterator pstr = str.begin( );
        //  排除前导的空格
        while (*pstr == ' ')          //  排除前导的空格
        {
            pstr++;
        }

        bool minus = false;

        //  判断符号位+ -
        if (*pstr == '+')
        {
            pstr++;
        }
        else if (*pstr == '-')
        {
            pstr++;
            minus = true;
        }


        long long int value = 0;
        for (; pstr != str.end( ); pstr++)
        {
            if ('0' <= *pstr && *pstr <= '9')
            {
                value *= 10;
                value += *pstr - '0';
                debug <<"value = "<<value <<endl;
            }
            else
            {
                break;
            }

            //  解决OVER_FLOW的问题
            //  INT_MAX     2147483647
            //  INT_MIN     -2147483648  minus = true
            if((minus == true  && value > (unsigned long)(INT_MAX) + 1)     //  负数绝对值最大为INT_MAX + 1
            || (minus == false && value > INT_MAX))                         //  正数最大值为INT_MAX
            {
                debug <<value <<", " <<INT_MAX + 1 <<endl;
                debug <<"to max than int" <<endl;
                break;
            }

        }
        if(pstr != str.end( ))
        {
            return 0;
        }
        else
        {

            if (minus == true)
            {
                value = -value;
            }

            if (value >= INT_MAX)
            {
                value = INT_MAX;
            }
            else if (value <= INT_MIN)
            {
                value = INT_MIN;
            }

            return (int)value;

        }
    }
};


int __tmain(void)
{
    Solution solu;
    cout <<"INT_MAX" <<INT_MAX <<endl;
    cout <<"INT_MIN" <<INT_MIN <<endl;
    cout <<solu.StrToInt("1a33") <<endl;
    cout <<solu.StrToInt("-2147483648") <<endl;


    return EXIT_SUCCESS;
}

其中

value * 10 -=> (value << 1) + (value << 3)
*pstr - '\0' -=> *pstr & 0xf

因此

value *= 10;
value += *pstr - '0';

可以用如下代码代替

value = (value << 1) + (value << 3) + (*pstr & 0xf); //value = value*10+(*pstr-‘0’);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值