如大家所了解的,状态机,又名有限状态机,自动机。
指的是在限定环境中,根据规律抽象成的数学模型。具体的模型可以作为一种状态产生不同的作用,并且状态间可以进行转换。
在许多算法中,尤其是很多字符串相关算法,如 KMP,AC 自动机等,都会使用该思路。并且在各种实际项目的底层逻辑中也是使用的状态机这一模型进行管理。
此处,引入一道比较简单与典型的字符串处理的题目。
字符串转换整数 (atoi)
题意简述:给定一个字符串,将该字符串解析成一个 32 位的整数。规定,可以有前导空格,存在 ± 号的表示,此后读到首个非数字字符表示结束。并将结果收缩到 [−2^{31}, 2^{31} − 1] 间。
类似 C/C++ 中的 atoi 函数,具体的细节描述可以查看上面的链接。
注意:本文对一些细节,如怎么判断数字是否越界等问题不会着重介绍,主要是为了展示状态的表示与转移。
普通流程化写法
整体的处理顺序也比较明朗,用一张流程图来说是这样的:
其实根据题意可以将其分为三大步骤:
1. 处理前导空格
处理完毕后,开始真正的数据处理;
2. 处理正负号
处理完毕后,开始真正的数值处理;
3. 处理数值
处理完毕后,整体处理完毕。作用上正负号标记,就可以获得最终的答案。
class Solution { public: int myAtoi(string s) { const int n = s.size(); int i = 0; // 略过空格 while (i < n && s[i] == ' ') { i += 1; } int sign = 1; // 处理符号 if (i < n && (s[i] == '+' || s[i] == '-')) { sign = (s[i] == '+') ? 1 : -1; i += 1; } int ans = 0; // 遍历,获取答案 for (; i < n; i += 1) { // 遇到首个非数字字符,则终止 if (! isdigit(s[i])) { break; } int digit = s[i] - '0'; // 要到最值了 if (ans > (INT_MAX - digit) / 10) { return (sign == 1) ? INT_MAX : INT_MIN; } ans = ans * 10 + digit; } return ans * sign; } };