首页 > 其他 > 详细

leetcode题解之字符串转换整数 (atoi)

时间:2020-06-05 15:46:20      阅读:34      评论:0      收藏: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 (?231) 。

??文字题解

方法一:自动机

思路

字符串处理的题目往往涉及复杂的流程以及条件情况,如果直接上手写程序,一不小心就会写出极其臃肿的代码。

因此,为了有条理地分析每个输入字符的处理方法,我们可以使用自动机这个概念:

我们的程序在每个时刻有一个状态 s,每次从序列中输入一个字符 c,并根据字符 c 转移到下一个状态 s‘。这样,我们只需要建立一个覆盖所有情况的从 sc 映射到 s‘ 的表格即可解决题目中的问题。

算法

本题可以建立如下图所示的自动机:

技术分享图片

我们也可以用下面的表格来表示这个自动机:

‘ ‘ +/- number other
start start signed in_number end
signed end end in_number end
in_number end end in_number end
end end end end end

接下来编程部分就非常简单了:我们只需要把上面这个状态转换表抄进代码即可。

另外自动机也需要记录当前已经输入的数字,只要在 s‘in_number 时,更新我们输入的数字,即可最终得到输入的数字。

INT_MAX = 2 ** 31 - 1
INT_MIN = -2 ** 31

class Automaton:
def init(self):
self.state = ‘start‘
self.sign = 1
self.ans = 0
self.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‘],
}

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_col</span><span class="hljs-params">(self, c)</span>:</span>
    <span class="hljs-keyword">if</span> c.isspace():
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
    <span class="hljs-keyword">if</span> c == <span class="hljs-string">‘+‘</span> <span class="hljs-keyword">or</span> c == <span class="hljs-string">‘-‘</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
    <span class="hljs-keyword">if</span> c.isdigit():
        <span class="hljs-keyword">return</span> <span class="hljs-number">2</span>
    <span class="hljs-keyword">return</span> <span class="hljs-number">3</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self, c)</span>:</span>
    self.state = self.table[self.state][self.get_col(c)]
    <span class="hljs-keyword">if</span> self.state == <span class="hljs-string">‘in_number‘</span>:
        self.ans = self.ans * <span class="hljs-number">10</span> + int(c)
        self.ans = min(self.ans, INT_MAX) <span class="hljs-keyword">if</span> self.sign == <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> min(self.ans, -INT_MIN)
    <span class="hljs-keyword">elif</span> self.state == <span class="hljs-string">‘signed‘</span>:
        self.sign = <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> c == <span class="hljs-string">‘+‘</span> <span class="hljs-keyword">else</span> <span class="hljs-number">-1</span>

class Solution:
def myAtoi(self, str: str) -> int:
automaton = Automaton()
for c in str:
automaton.get(c)
return automaton.sign * automaton.ans


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"}}
};

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">get_col</span><span class="hljs-params">(<span class="hljs-keyword">char</span> c)</span> </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isspace</span>(c)) <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span> (c == <span class="hljs-string">‘+‘</span> <span class="hljs-keyword">or</span> c == <span class="hljs-string">‘-‘</span>) <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isdigit</span>(c)) <span class="hljs-keyword">return</span> <span class="hljs-number">2</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-number">3</span>;
}

public:
int sign = 1;
long long ans = 0;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">get</span><span class="hljs-params">(<span class="hljs-keyword">char</span> c)</span> </span>{
    state = table[state][get_col(c)];
    <span class="hljs-keyword">if</span> (state == <span class="hljs-string">"in_number"</span>) {
        ans = ans * <span class="hljs-number">10</span> + c - <span class="hljs-string">‘0‘</span>;
        ans = sign == <span class="hljs-number">1</span> ? min(ans, (<span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span>)INT_MAX) : min(ans, -(<span class="hljs-keyword">long</span> <span class="hljs-keyword">long</span>)INT_MIN);
    }
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (state == <span class="hljs-string">"signed"</span>)
        sign = c == <span class="hljs-string">‘+‘</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>;
}

};

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

复杂度分析

  • 时间复杂度:O(n)O(n),其中 nn 为字符串的长度。我们只需要依次处理所有的字符,处理每个字符需要的时间为 O(1)O(1)

  • 空间复杂度:O(1)O(1),自动机的状态只需要常数空间存储。

leetcode题解之字符串转换整数 (atoi)

原文:https://www.cnblogs.com/leetcodetijie/p/13049838.html

(0)
(0)
   
举报
评论 一句话评论(0
分享档案
最新文章
教程昨日排行
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!