把字符串转换成整数

请你写一个函数 StrToInt,实现把字符串转换成整数这个功能。

当然,不能使用 atoi 或者其他类似的库函数。

数据范围

输入字符串长度 [0,20]。

样例
输入:"123"

输出:123

注意:

你的函数应满足下列条件:

  1. 忽略所有行首空格,找到第一个非空格字符,可以是 ‘+/−’ 表示是正数或者负数,紧随其后找到最长的一串连续数字,将其解析成一个整数;
  2. 整数后可能有任意非数字字符,请将其忽略;
  3. 如果整数长度为 0,则返回 0;
  4. 如果整数大于 INT_MAX(2^{31}-1),请返回 INT_MAX;如果整数小于INT_MIN(-2^{31}) ,请返回 INT_MIN;

class Solution {
public:
    int strToInt(string str) {
        //按照题目来,这是跳过空格的操作。
        int k=0;
        while(k<str.size()&&str[k]==' ') k++;
/*k是我自己定义的游走的数组下标,我自己喜欢把他当成"指针",这样舒服一点。
当k是数组下标,最多达到str.size()-1,所以这里是小于str.size()的,并且发现这位为空就跳过,
这就是题中所谓的忽略所有行首空格,初始化为0就右两种含义:在这里一是本来就要初始化,二就是这里去除行首空格,也要从0号位开始,所以就这样做。*/

        //判断符号的操作
        int sign=1;
        if(k<str.size()&&(str[k]=='+'||str[k]=='-')){
/*继续操作,当找到了非空字符,k指针就不会跳过了,不会跳过的话我们就得判断了,如果说是
'+'或者'-'这种符号,那么输出的结果最前面肯定会有正负,所以我们得在这里判断,这样最后返回最终结果的时候才不会错。
首先,这个k还是得保证在数组操作范围内,所以有k<str.size(),若是同时满足这一位上有'+'或者'-'这种符号出现,那么就得进行相应的准备,那就是下面的部分代码。*/
            if(str[k]=='+'){
                sign=1;
                k++;
            }else{
             sign=-1;
             k++;
            }
        }
/*若是k位置上的字符为'+',表示最后输出的结果是正数,所以把sign标记为1,为后面使用。
若是'-',说明最后结果为负数,最后得到的结果前面要多个'-',所以这里把sign标记为-1,也是为后面用*/



        //结果整数的构造。
        long long res=0;
        while(k<str.size()&&isdigit(str[k])){
            res=res*10+(str[k]-'0');
            k++;

/*经过前面的判断与操作,若是更新后的k位上是数字字符,那么就有了这个操作。
首先k还是得在数组操作范围内,不得越界,所以仍有k<str.size(),若这个时候同时满足k位上是数字字符,那就可以操作了,怎么判断这个k位上的字符是不是数字呢,所以这里使用了c++里面的isdigit函数来判断,若是数字字符就可以满足while语句的条件,就可以继续进行下面的操作,不是则不行。*/


/*最值得注意的来了,得到这个是数字字符后,不能直接的使用,哪怕真的是一个数字,因为在前面别人给我们定义的就知道了,题目给我们的时候,已经将要输入的字符串定义为string类型的了,也就是那个string str,也就是说str[k]上每一位上的东西都是字符,所以要先转化为数字,然后进行操作,所以有把
当前k位上的字符数字转化为数字的式子,那就是:str[k]-'0',这个'0'是ascii码,不是数值0,字符之间的运算都是先转化为ascii码然后再计算,所以这里成功的将数字字符转化为了数值。然后我们看输入的样例,"123"最后我们要得到的是123,不是1 2 3这三个数字,说明最后得到的必须是货真价实的整数,所以
我们仔细观察,如果说紧挨着的几位上都是数字,就可以发现,因为k是从左往后的,数字的位数变多,值会增大,他们的规律都是k位置上面的数值加上前面位乘10的和,就是最终结果,所以有那个res的计算式子,
当k位上的值使用完,并计算出了当前的值后,k会继续往后移动,不会停滞不前的,这里要注意,要k++,很容易忽视这个。*/



            //最后的注意输出,根据题意。
            if(res*sign> INT_MAX)  return  INT_MAX;
            if(res*sign< INT_MIN)  return  INT_MIN;

/*这个就是检查,按照题目的要求来的判断,就是把算出来的结果跟这个比较就是,不难。
        }
        //最后返回的是值(带符号的),所以返回这个。
        return res*sign;
    }
};

补充:

1、在 C++ 中,isdigit 是一个函数,用于判断一个字符是否是数字字符。它是 C 标准库 <cctype> 头文件中的函数,其原型定义如下:

int isdigit( int ch );

函数接受一个整数参数 ch,通常是一个字符的 ASCII 值。它返回一个非零值(通常是 1),如果 ch 是一个十进制数字字符(即 '0' 到 '9'),否则返回 0。

例如:

  • isdigit('0') 返回非零值(通常是 1),因为 '0' 是一个数字字符。
  • isdigit('5') 也返回非零值,因为 '5' 也是一个数字字符。
  • isdigit('a') 返回 0,因为 'a' 不是数字字符。

在字符串处理中,常常使用 isdigit 来检查字符是否是数字,例如在字符串转换成整数的过程中,可以使用它来判断字符是否是有效的数字字符。

这个题算是比较难的了,是剑指offer里面的题,而且这个样子的代码样子就是力扣里面的那种模式,会给你定义一些东西,一定要注意看,我也是没接触这种形式多久,还在习惯,这种相当于是只要把他给的函数补充完整就行,把大体逻辑弄出来就可以,那些细节的什么定义和啥的,就默认别人帮你做好了,就不用管那么多,反正这是个难题,也是我适应的一个难题。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值