LeetCode字符串转换整型

该博客介绍了如何实现一个类似于C/C++的atoi函数,将字符串转换为32位有符号整数。文章详细阐述了转换算法,包括处理前导空格、正负号、数字截断以及越界检查,并通过举例说明了不同情况的处理。代码实现中涉及了字符串遍历、栈操作以及数值溢出的判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:
读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,"123" -> 123"0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [231,  2311] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 2311 的整数应该被固定为 2311 。
返回整数作为最终结果。

注意:
本题中的空白字符只包括空格字符 ' ' 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

示例 1:
输入:s = "42"
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
         ^2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+'^3 步:"42"(读入 "42"^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。

示例 2:
输入:s = "   -42"
输出:-42
解释:
第 1 步:"   -42"(读入前导空格,但忽视掉)
            ^2 步:"   -42"(读入 '-' 字符,所以结果应该是负数)
             ^3 步:"   -42"(读入 "42"^
解析得到整数 -42 。
由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。

示例 3:
输入:s = "4193 with words"
输出:4193
解释:
第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格)
         ^2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+'^3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止)
             ^
解析得到整数 4193 。
由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193

题解

这道题,太恶心了,我花了很久时间才通过,倒不是因为难,就是很多小的地方需要扣。
这道题简单来说就分四种情况:

1.不合法情况(也就是最开始就不合法):
首位字符不是数字、正负号、空格,这样的情况直接返回0就行
2.首位是0
首位是0的时候,又分两种情况:
1)0后面跟的数字
	这种情况是合法情况,直接进行遍历字符串,入栈之后出栈计算最终结果即可;
2)0后面跟的字符
	这种情况直接返回0,因为不合法;
3.首位是正负号
首位是正负号的又分两种情况:
1)空格完后是数字
	跟上面的操作一样,入栈,出栈计算;
2)正负号(只能是正负号,其余的不行)
	就从正负号后面开始遍历,入栈,出栈计算;
4.首位是空格
首位是正负号的情况同样包含了两种
1)后面跟是的0
2)正常数字
	这两种情况,直接入栈,出栈计算就行,因为0不影响后面的最终结果;

除了以上所述的情况,其余情况都是非法情况

那么直接上代码:

class Solution {
public:
    int myAtoi(string s) {
    	/*考虑使用栈来实现
        合法情况:1.首位为数字;2.首位为正负号;3.首位为空格 就这三种合法情况
        首位是数字中又分首位为0和首位不为0
        首位是空格中包含了空格完后是数字和正负号(只能是正负号,其余的不行)
        首位是正负号的情况就包含了后面跟是的0和正常数字,其余均为0
        */
       //排除调不合法情况
       int res = 0,top=-1;//结果和栈顶指针
       if((s[0]-'0'>=17 && s[0]-'0'<=42) || (s[0]-'0'>=49 && s[0]-'0'<=74) || 
       (s[0]-'0'==-2))
       {
            res = 0;
            std::cout<<res<<endl;
            return res;
       }
       //合法情况
       int stack[500000]={0};
       //如果第一位是数字
       if(s[0]-'0'>=0 && s[0]-'0'<=9)
       {
            int flag = 0;
            if(s[0]=='0')//首位是0
            {
                for(int i=1;i<s.size();i++)
                {
                    if(!(s[i]-'0'>=0 && s[i]-'0'<=9))//如果0后面跟的不是数字
                    {
                        res = 0;
                        cout<<res<<endl;
                        return res;
                    }
                    else if(s[i]-'0'>=1 && s[i]-'0'<=9){
                        s = s.substr(i, (s.size()-i));//截取当前位置到末尾
                        cout<<s<<endl;
                        break;
                    }
                }
                for(int i=0;i<s.size();i++)
                {
                    if(s[i]-'0'>=0 && s[i]-'0'<=9)//如果当前是数字,则入栈
                    {
                        stack[++top] = s[i] - '0';
                    }
                    else
                    {
                        break;
                    }
                }
                //计算结果,出栈
                for(;top>-1;top--)
                {
                    if(res+stack[top]*pow(10,flag)<=2147483647)//判断是否溢出
                    {
                        res += stack[top]*pow(10,flag);
                        ++flag;
                    }
                    else
                    {
                        res = 2147483647;
                        break;
                    }
                }
            }
            else if(s[0]-'0'>=1 && s[0]-'0'<=9)//首位是非零数字
            {
                //直接循环入栈
                stack[++top]=s[0]-'0';
                for(int i=1;i<s.size();i++)
                {
                    if(!(s[i]-'0'>=0 && s[i]-'0'<=9))//如果当前不是数字
                    {
                        break;
                    }
                    else
                    {
                        stack[++top]=s[i]-'0';
                    }
                }
                for(;top>-1;top--)
                {
                    if(res+stack[top]*pow(10,flag)<=2147483647)//判断是否溢出
                    {
                        res += stack[top]*pow(10,flag);
                        ++flag;
                    }
                    else
                    {
                        res = 2147483647;
                        break;
                    }
                }
                
            }
       }
       /*首位是空格的情况*/
       else if(s[0]==' ')
       {
            int flag = 0;
            for(int i=1;i<s.size();i++)
            {
                if(s[i]!=' ')//如果当前位置不是空格
                {
                    if(!(s[i]-'0'>=0 && s[i]-'0'<=9) && s[i]!='+' && s[i]!='-')//不是数字,不是正负号,直接非法
                    {
                        res = 0;
                        return res;
                    }
                    //合法
                    else{
                        if(s[i]=='+' || s[i]=='-')//如果空格后面是正负号
                        {
                            if(s[i]=='-')
                            {
                                s=s.substr(i,s.size()-i);//把负号算进去
                                cout<<s<<endl;
                                break;
                            }
                            else
                            {
                                s=s.substr(i+1,s.size()-i);//从符号位的下一位截取到末尾
                                cout<<s<<endl;
                                break;
                            }
                        }
                        else if(s[i]-'0'>=0 && s[i]-'0'<=9)//如果空格后面是数字
                        {
                            s=s.substr(i,s.size()-i);//从当前截取
                            cout<<s<<endl;
                            break;
                        }
                    }
                }
            }
            for(int i=(s[0]=='-'?1:0);i<s.size();i++)
            {
                if(s[i]-'0'>=0 && s[i]-'0'<=9)
                {
                    stack[++top]=s[i]-'0';//入栈
                }
                else
                {
                    break;
                }
            }
            for(;top>-1;top--)
            {
                // res+=stack[top]*pow(10,flag);
                // ++flag;
                if(s[0]=='-')
                {
                    if(res+(-(stack[top]*pow(10,flag)))>=-2147483648)//负数的情况
                    {
                        res+=-(stack[top]*pow(10,flag));
                        ++flag;
                    }
                    else
                    {
                        res = -2147483648;
                    }
                }
                else
                {
                    if(res+stack[top]*pow(10,flag)<=2147483647)
                    {
                        res+=stack[top]*pow(10,flag);
                        ++flag;
                    }else res=2147483647;
                }
            }
       }
       else if(s[0]=='+' || s[0]=='-')//首位是正负号的情况
       {
            int flag=0;
            if(!(s[1]-'0'>=0 && s[1]-'0'<=9))//符号后面不是数字,直接非法
            {
                res = 0;
                return res;
            }
            else
            {
                for(int i=1;i<s.size();i++)
                {
                    if(s[i]-'0'>=0 && s[i]-'0'<=9)
                    {
                        stack[++top]=s[i]-'0';//入栈
                    }
                    else
                    {
                        break;
                    }
                }
                for(;top>-1;top--)
                {
                    // res+=stack[top]*pow(10,flag);
                    // ++flag;
                    if(s[0]=='-')
                    {
                        if(res+(-(stack[top]*pow(10,flag)))>=-2147483648)//负数的情况
                        {
                            res+=-(stack[top]*pow(10,flag));
                            ++flag;
                        }
                        else
                        {
                            res = -2147483648;
                        }
                    }
                    else
                    {
                        if(res+stack[top]*pow(10,flag)<=2147483647)
                        {
                            res+=stack[top]*pow(10,flag);
                            ++flag;
                        }else res=2147483647;
                    }
                }
            }
       }
       std::cout<<res<<endl;
       return res;
    }
};

最后跑出来的情况其实不太好(相比较大家的提交情况而言),这道题烦就烦在需要考虑很小的地方,比如int型越界的时候,需要判断是否越界,如果越界应该怎么做,还有就是符号的考虑,太细太细了!!
写到最后我才意识到,我的这个代码,有部分可以改改,比如数字的入栈,首位是0的情况,其实可以直接入队,反正0不影响最终结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值