题目
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)
leetcode链接
思路
直接写:
- 跳过前导空白符‘’
- 判断首字母是否是‘+’、‘-’,记录sign
- 如果是数字,则进行计算
- 判断是否大于最大值或者小于最小值
惭愧的是这个也写了很多遍才对,面向bug编程==
但是看了答案发现,我去,竟然用了自动状态机,我太low了,还没写过自动状态机,之后要补一个
解答
算法1:普通算法
var myAtoi = function(s) {
let reg = /[0-9]/
let result = 0
const max = Math.pow(2, 31) - 1
const min = Math.pow(-2, 31)
let j = 0
let sign = 1
while (j < s.length && s[j]== ' ') {
j++
}
for (let i = j; i < s.length; i++) {
let val = s[i]
if (i == j && val == '+') {
continue
}
if (i == j && val == '-') {
sign = -1
continue
}
val = parseInt(val, 10)
if (!reg.test(val)) {
return result
}
result = result * 10 + sign * val
if (result < min) {
return min
}
if (result > max) {
return max
}
}
return result
};
解答时遇到的问题:
- 指数求解api:Math.pow();忘记了,还查了查
Math.pow(2, 31) - 1;Math.pow(-2, 31) - 一开始记录正负,用了flag,其实直接用sign记录1,-1就可以
- 优先把前导符过滤掉,否则会出现+-123 case失败的情况
算法2: 自动状态机
占位。。
最后,今天让我们看看chatgpt的解答:咦,它写的简单解法,没有自动状态机
代码cp如下:
function myAtoi(s) {
const INT_MAX = Math.pow(2, 31) - 1; // 32位有符号整数的最大值
const INT_MIN = Math.pow(-2, 31); // 32位有符号整数的最小值
let i = 0;
let sign = 1; // 符号,默认为正数
let result = 0;
// 跳过前面的空白字符
while (i < s.length && s[i] === ' ') {
i++;
}
// 处理符号位
if (i < s.length && (s[i] === '-' || s[i] === '+')) {
sign = s[i] === '-' ? -1 : 1;
i++;
}
// 处理数字字符
while (i < s.length && s[i] >= '0' && s[i] <= '9') {
const digit = parseInt(s[i]);
// 检查是否溢出
if (result > Math.floor(INT_MAX / 10) || (result === Math.floor(INT_MAX / 10) && digit > 7)) {
return sign === 1 ? INT_MAX : INT_MIN;
}
result = result * 10 + digit;
i++;
}
// 返回结果
return result * sign;
}
附代码:
function myAtoi(s) {
// 定义状态常量
const State = {
START: 0,
SIGN: 1,
NUM: 2,
END: 3
};
// 初始化状态和结果
let state = State.START;
let result = 0;
let sign = 1;
// 定义状态转换表
const stateTable = [
[State.START, State.SIGN, State.NUM, State.END], // 状态 START 的转换表
[State.END, State.END, State.NUM, State.END], // 状态 SIGN 的转换表
[State.END, State.END, State.NUM, State.END], // 状态 NUM 的转换表
[State.END, State.END, State.END, State.END] // 状态 END 的转换表
];
// 迭代字符串
for (let i = 0; i < s.length; i++) {
const char = s[i];
let col;
// 确定字符属于哪一列
if (char === ' ') {
col = 0; // 空格
} else if (char === '-' || char === '+') {
col = 1; // 符号
} else if (char >= '0' && char <= '9') {
col = 2; // 数字
} else {
col = 3; // 其他字符
}
// 获取下一状态
state = stateTable[state][col];
// 检查状态
if (state === State.START || state === State.SIGN) {
continue; // 继续处理下一个字符
} else if (state === State.NUM) {
// 将数字字符转换为数字,并累加到结果
result = result * 10 + parseInt(char);
// 检查是否溢出
if (result * sign > Math.pow(2, 31) - 1) {
return Math.pow(2, 31) - 1;
} else if (result * sign < -Math.pow(2, 31)) {
return -Math.pow(2, 31);
}
} else {
break; // 遇到无效字符,退出循环
}
}
return result * sign;
}