字符串转换成整数(3种方法)

算法 同时被 3 个专栏收录
32 篇文章 0 订阅
33 篇文章 0 订阅
19 篇文章 0 订阅

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0 。

提示:

本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:

输入: “42”
输出: 42
示例 2:

输入: " -42"
输出: -42
解释: 第一个非空白字符为 ‘-’, 它是一个负号。
我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
示例 3:

输入: “4193 with words”
输出: 4193
解释: 转换截止于数字 ‘3’ ,因为它的下一个字符不为数字。
示例 4:

输入: “words and 987”
输出: 0
解释: 第一个非空字符是 ‘w’, 但它不是数字或正、负号。
因此无法执行有效的转换。
示例 5:

输入: “-91283472332”
输出: -2147483648
解释: 数字 “-91283472332” 超过 32 位有符号整数范围。
因此返回 INT_MIN (−2^31) 。

C++
初稿

class Solution {
public:
    int myAtoi(string s) {
        int i=0;
        bool fu = false;
        bool chara = false;
        vector <int> result;
        if(!s[0])
            return 0;
        
        while(s[i]==' ')
        {
            i++;
        }
        if(s[i]=='-'&&fu==false&&chara==false)
            {
                fu=true;
                chara = true;
                i++;
            }
        if(s[i]=='+'&&chara==false)
            {
                chara = true;
                i++;
            }
        while(s[i]=='0')
        {
            i++;
            chara=true;
        }
        while(i<s.size())
        {


            if(s[i]>='0'&&s[i]<='9')
            {
                chara = true;
                result.push_back(s[i]-'0');
            }
            else
                break;
            i++;

        }

        long sum=0;
        int len = result.size();
        i=0;
        if(len>10&&fu==false)
            return INT_MAX;
        if(len>10&&fu==true)
            return INT_MIN;
        while(i<result.size())
        {
            sum += pow(10,len-1)*(result[i]);
            i++;
            len--;
        }
        if(fu)
            sum = -sum;
        if(sum<INT_MIN)
            return INT_MIN;
        if(sum>INT_MAX)
            return INT_MAX;

        return sum;
    }
};

优化后

class Solution {
public:
    int myAtoi(string s) {
        int i=0;
        bool fu = false;
        while(s[i]==' ')
        {
            i++;
        }
        if(s[i]=='-')
            {
                fu=true;
            }
        if(s[i]=='+'||s[i]=='-')
            {
                i++;
            }
        int sum=0;
        while(i<s.size()&&isdigit(s[i]))
        {

            int r = s[i]-'0';

            if(sum>INT_MAX/10||(INT_MAX/10==sum&&r>7))//也可用double,不过会慢。
                return fu? INT_MIN:INT_MAX;
            sum = sum*10 + r;
            i++;
        }

        return fu? -sum:sum;
    }
};

答案用的自动机DFA

在这里插入图片描述

在这里插入图片描述

class Automaton {
    string state = "start";
    unordered_map<string, vector<string>> table = {
        {"start", {"start", "signed", "in_number", "end"}},
        {"signed", {"end", "end", "in_number", "end"}},
        {"in_number", {"end", "end", "in_number", "end"}},
        {"end", {"end", "end", "end", "end"}}
    };

    int get_col(char c) {
        if (isspace(c)) return 0;
        if (c == '+' or c == '-') return 1;
        if (isdigit(c)) return 2;
        return 3;
    }
public:
    int sign = 1;
    long long ans = 0;

    void get(char c) {
        state = table[state][get_col(c)];
        if (state == "in_number") {
            ans = ans * 10 + c - '0';
            ans = sign == 1 ? min(ans, (long long)INT_MAX) : min(ans, -(long long)INT_MIN);
        }
        else if (state == "signed")
            sign = c == '+' ? 1 : -1;
    }
};

class Solution {
public:
    int myAtoi(string str) {
        Automaton automaton;
        for (char c : str)
            automaton.get(c);
        return automaton.sign * automaton.ans;
    }
};


附一个一行的python代码

class Solution:
    def myAtoi(self, s: str) -> int:
        return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)

由这个python代码想到了正则表达式
C++的正则表达式方法

class Solution {
public:
        int sign = 1;
        int myAtoi(string s) {
        s.erase(0,s.find_first_not_of(" "));
        regex e("^[\\+\\-]?\\d+");
        smatch m;
        bool found = regex_search(s, m, e); 
        int ans = 0;
        string resu = m.str(0);
        if(resu[0]=='-')
        {
            sign = -1;
        }
        if(resu[0]=='+'||resu[0]=='-')
        {
            resu.erase(0,1);
        }
        for(char c : resu)
            {
            int num = c - '0';
            if(ans>INT_MAX/10||(ans==INT_MAX/10&&num>7))
            {
                return sign==1? INT_MAX:INT_MIN;
            } 
            ans = ans * 10 + num;
            }
            return sign * ans;
    }   
};
  • 0
    点赞
  • 0
    评论
  • 7
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

_yuan20

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值