有穷自动机解决字符串转整数
1. 要求
- 第一非空字符为正负号后跟连续数字,非数字字符及其后忽略
- 第一非空数字后跟连续数字,非数字字符及其后忽略
- 范围表示int上下界,超出则以上下界值表示
- 其余非法,0表示
2. 方法
1. 直接法
针对各种条件,直接编写(python):
- 空字符串
- 首非空字符为不是数字及正负号
- 所转换数字越界
- 连续数字后接非数字字符
def myAtoi(s):
"""
:type s: str
:rtype: int
"""
s = s.strip()
if len(s) == 0:
return 0
flag = False #符号标志
index = 0
res = 0
int_max = 0x7fffffff
int_min = -int_max - 1
if s[0] == '-':
flag = True
index += 1
elif s[0] == '+':
index += 1
elif s[0] > '9' or s[0] < '0': #第一非空字符非数字,非正负号
return 0
while index < len(s): #包括考虑上下界
if s[index] >= '0' and s[index] <= '9':
if not flag and (res > int_max/10 or res == int_max/10 and int(s[index]) > 7):
return int_max
if flag and (res > int_max/10 or res == int_max/10 and int(s[index]) > 8):
return int_min
res = res*10 + int(s[index])
else: #后出现非数字字符,直接结束转换
break
index += 1
if flag:
res = -res
return res
2. 有穷自动机(状态机)
记录所有状态转移的情况,结合上一状态和当前条件确定当前状态。
- start为开始状态,遇到空格则继续保持开始状态,直到遇到正负号转为sign状态,数字则转为number状态(即开始整数转换),其他字符则直接结束转换
- sign状态和number状态只有在遇到数字字符才能继续转换,此时转为number状态
- end状态直接结束
" " | +/- | num | else | |
---|---|---|---|---|
start | start | sign | number | end |
sign | end | end | number | end |
number | end | end | number | end |
end | end | end | end | end |
代码:
def myAtoi1(self, s):
table = {'start': ['start', 'sign', 'number', 'end'],\
'sign': ['end', 'end', 'number', 'end'],\
'number': ['end', 'end', 'number', 'end'],\
'end': ['end', 'end', 'end', 'end']} #状态转移表
INT_MAX = 0x7fffffff
INT_MIN = -INT_MAX - 1 #边界值
state = 'start' #初始状态
sign = False #符号
res = 0
for i in range(len(s)): #当前字符值,获得表的列值
col = 0
if s[i].isspace():
col = 0
elif s[i] == '-' or s[i] == '+':
col = 1
elif s[i].isdigit():
col = 2
else:
col = 3
state = table[state][col] #转移后的状态
if state == 'end':
break
elif state == 'sign':
sign = True if s[i] == '-' else False
elif state == 'number':
res = res * 10 + int(s[i])
if sign and -res < INT_MIN: #界判定
return INT_MIN
if not sign and res > INT_MAX:
return INT_MAX
if sign:
res = -res
return res