Leetcode008 string-to-integer-atoi

字符串转换整数 (atoi)

题目描述:

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

 首先该函数会根据丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
 该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:
 假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。
 在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:
 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,qing返回 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) 。

补充知识:

这一题考查的是正则化re模块的使用 https://blog.csdn.net/weixin_40583388/article/details/78458610

  • \d 匹配所有的数字

  • \D 匹配所有,但是数字除外

  • \s 空格

  • \S 匹配所有但是空格除外

  • \w 匹配所有的字母

  • \W 匹配所有但是字母除外 . 任意除换行符

  • \n . 表示点符号,斜杠本身是转义字符

常见的表达式举例:

  • {1,3} 表示数字1到3范围
  • “+” 匹配1个或者更多
  • ?匹配0个或者1个结果
  • “ * ” 匹配0个或者更多结果
  • $ 匹配字符串的结尾部分
  • ^ 匹配字符串的开始部分
  • | 匹配左右表达式任意一个
  • [] 字符集任意范围,例如[A-Z]表示大写A到Z
  • {x} 计算一共找到x的数量

常用的元字符有以下几种

https://www.jianshu.com/p/95849a7df81c

.元字符:

pattm=re.compile('.',re.S)   #re.s代表匹配的模式,我们这里选择了所有的匹配模式,所有换行符也会被匹配
pstr=pattm.findall('abcd1234\n')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
 >>> ['a', 'b', 'c', 'd', '1', '2', '3', '4', '\n']

. 代表一个任意的字符,这个字符默认包含所有的不包括换行符在内的所有字符,但通过改变匹配的模式,我们也可以做到匹配换行符,所有结果中返回了所有的匹配的结果!

^ 元字符:

pattm=re.compile('^abc',re.S)  #匹配abc为开头的字符
 pstr=pattm.findall('abcd1234\n')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
 >>>  ['abc']   

^ 号表示匹配开头,上面例子我们相当于匹配字符串abc,切记这里不是匹配到整个abc开头的字符串哦!

$ 元字符:

 pattm=re.compile('abc$',re.S)
  pstr=pattm.findall('abcd1234abc')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
        
  >>> ['abc']

$ 表示匹配结尾,上面例子就是相当于匹配abc,注意不是得到整个以abc结尾的字符串!

*元字符:

 pattm=re.compile('a*',re.S)  #找出所有0个a乃至n个a的匹配
pstr=pattm.findall('bcaacaaab')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
        
 >>> ['', '', 'aa', '', 'aaa', '', '']

*代表倍数,只对该符号前一个字符有效,可以是0倍也可以是任意倍数,所以上面结果中,返回了空字符,因为0倍就是空字符!!

+ 元字符:

 pattm=re.compile('a+',re.S)
pstr=pattm.findall('bcaacaaab')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
>>>  ['aa', 'aaa']

元字符+和元字符*有点类似,只对该符号前一个字符有效,也是指重复,但是+不能匹配0倍,这是根本区别!

? 元字符:

pattm=re.compile('ca?t',re.S)  
 pstr=pattm.findall('catdddct')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
        
   >>> ['cat', 'ct']   

元字符?号也是重复类字符,但他表示可选,上面例子中a字符表示可选字符,他可匹配也可以不匹配,所以返回了两种匹配结果!

{ } 元字符:
元字符{} 也是重复字符中的一员,只对该符号前一个字符有效,他比+和*更加的灵活

pattm=re.compile('a{1,2}',re.S)   #最少匹配1个a,最多匹配两个a
pstr=pattm.findall('fcabcdaaaef^')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
  >>> ['a', 'aa', 'a'] 

{}字符中可以有两个变量{m,n}, m表示最少的匹配倍数,n表示最大的匹配倍数.也可以只写一个变量{n},表示最大匹配n倍字符!

[] 元字符:

pattm=re.compile('[abc]',re.S)
pstr=pattm.findall('abcdef')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
 >>> ['a', 'b', 'c']

元字符[] 表示一个范围,相当于指定匹配一个范围类的字符,上图中想到与能匹配a,b,c三个字符范围,也可以写成[a-b]两者的效果相同,很多手机号的正则就是利用了该元字符,比如[0-9]取0到9范围内的一个数字!

还需要特别注意一点的是,在[]类中其他元字符将不会再有原有功能!
举个例子:

pattm=re.compile('[abc^]',re.S)  #按道理,^表示匹配开头,应该匹配abc开头的字符
pstr=pattm.findall('fcabcdef^')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
        
  >>> ['c', 'a', 'b', 'c', '^']  #但结果却可以看出,因为[]类的原因,^元字符的作用消失了,被当成了普通的一个字符,返回了所有[]内字符范围的匹配

>**\ 元字符:**

\字符是一个比较有意思的字符,他主要有两种功能
一种是转义:

pattm=re.compile('\{',re.S)   #将{转义成普通字符匹配
pstr=pattm.findall('fc{aa{ef[')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
  >>> ['{', '{']

我们可以通过\将其他的元字符当成普通字符来匹配!
第二种是组合序列,通过一些特定的组合,组合成了一些特定功能的序列,比如我们上面提到的特殊序列\s,\w等

| 元字符:

\字符是一个比较有意思的字符,他主要有两种功能
一种是转义:

pattm=re.compile('a|b',re.S)
pstr=pattm.findall('abcdbcda')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
 >>> ['a', 'b', 'b', 'a']

| 字符和java中的或有点类似,表示匹配前面部分或者后面部分,需要注意的是整个前面和后面部分!假如上面例子是abc|a表达式,表示匹配abc或者b,而不是先匹配ab,然后在c|a中选择一个,这种理解是错误的!

( ) 元字符:

()字符代表分组,代表一个整体

pattm=re.compile('(abc)',re.S)  #代表匹配abc字符
pstr=pattm.findall('abcccababab')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
  >>> ['abc']

当然()的用法远远不止上面这么简单,我们可以在()中加入任何的一个匹配规则组成一个组,就可以实现无数种功能

比如:

pattm=re.compile('(^abc.+)',re.S)
pstr=pattm.findall('abcccababab')
    if pstr!=None:
        print(pstr)
    else:
        print('无匹配!')
 >>> ['abcccababab']

上面’(^abc.+)’ 正则,如果你认真看了上面所有的元字符,应该不难理解,表示匹配abc开头的任意长度的字符串,所以上面返回了整个字符串.
还有一点需要注意,记得最上面我们使用match和search函数的时候,往往打印都会使用group函数,入下:

pattm=re.compile('(^abc.+)',re.S)
pstr=pattm.search('abcccababab')
    if pstr!=None:
        print(pstr.group())  #使用过了group函数
    else:
        print('无匹配!')

其实这里的group函数对应的就是一个正则中的()组,group(1)代表第一个出现的()组的匹配,groupe(1,3)代表出现的第1个和第三个()组的匹配!


解题思路:

  • 第一步是利用strip()函数来使字符串去空格
  • 第二步判断字符串的首位是否是数字或者是+/-号
  • 第三步将尽可能多的整数字符加入,知道出现空格或者是非数字字符

Python源码:

class Solution:
    def myAtoi(self, str: str) -> int:
        # 导入正则模块
        import re
        # 字符串中查找全部符合条件的整数,返回的是列表,第一个参数是正则,第二个参数是字符串
        # strip()字符串去空格
        ret = re.findall(r"^[-+]?\d+", str.strip())
        # 判断是否有匹配的值,没有的话返回0,例如"word values 987",匹配不到,返回0
        if ret:
            ret_str = ret[0]  # 匹配的数字的字符串
            ret_str2 = ""  # 记录去符号的字符串,ret_str后面还要使用,所以定义一个新的变量记录
            # 判断是否带有符号 + or -
            if ret_str[0] == "-" or ret_str[0] == "+":
                ret_str2 = ret_str[1:]
            else:
                ret_str2 = ret_str
            # str转int
            ret_int = int(ret_str2)
            # 判断第一个字符是否为负号
            if ret_str[0] == "-":
                # 三目运算符,判断是否溢出
                # 如果ret_int <= 2**31则返回-ret_int,否则返回-2**31
                return -ret_int if ret_int <= 2 ** 31 else -2 ** 31
            else:
                return ret_int if ret_int < 2 ** 31 else 2 ** 31 - 1
        else:
            return 0

欢迎关注我的github:https://github.com/UESTCYangHR

猜你喜欢

转载自blog.csdn.net/dzkdyhr1208/article/details/89086320
今日推荐