字符串转换整数JS

/** * @param {string} str * @return {number} */ var myAtoi = function(str) { // 自动机类 class Automaton{ constructor() { // 执行阶段,默认处于开始执行阶段 this.state = 'start'; // 正负符号,默认是正数 this.sign = 1; // 数值,默认是0 this.answer = 0; /* 关键点: 状态和执行阶段的对应表 含义如下: [执行阶段, [空格, 正负, 数值, 其他]] */ this.map = new Map([ ['start', ['start', 'signed', 'in_number', 'end']], ['signed', ['end', 'end', 'in_number', 'end']], ['in_number', ['end', 'end', 'in_number', 'end']], ['end', ['end', 'end', 'end', 'end']] ]) } // 获取状态的索引 getIndex(char) { if (char === ' ') { // 空格判断 return 0; } else if (char === '-' || char === '+') { // 正负判断 return 1; } else if (typeof Number(char) === 'number' && !isNaN(char)) { // 数值判断 return 2; } else { // 其他情况 return 3; } } /* 关键点: 字符转换执行函数 */ get(char) { /* 易错点: 每次传入字符时,都要变更自动机的执行阶段 */ this.state = this.map.get(this.state)[this.getIndex(char)]; if(this.state === 'in_number') { /* 小技巧: 在JS中,对字符串类型进行减法操作,可以将得到一个数值型(Number)的值 易错点: 本处需要利用括号来提高四则运算的优先级 */ this.answer = this.answer * 10 + (char - 0); /* 易错点: 在进行负数比较时,需要将INT_MIN变为正数 */ this.answer = this.sign === 1 ? Math.min(this.answer, Math.pow(2, 31) - 1) : Math.min(this.answer, -Math.pow(-2, 31)); } else if (this.state === 'signed') { /* 优化点: 对于一个整数来说,非正即负, 所以正负号的判断,只需要一次。 故,可以降低其判断的优先级 */ this.sign = char === '+' ? 1 : -1; } } } // 生成自动机实例 let automaton = new Automaton(); // 遍历每个字符 for(let char of str) { // 依次进行转换 automaton.get(char); } // 返回值,整数 = 正负 * 数值 return automaton.sign * automaton.answer; };
自动机
我们的程序在每个时刻有一个状态s,每次从序列中输入一个字符c,并根据字符c 转移到下一个状态s'。
这样,我们只需要建立一个覆盖所有情况的从s与c映射到s'的表格即可解决题目中的问题。
来源:力扣(LeetCode)
字符串str中的每个字符,都有可能是以下的四种类型中的一种:
- 空格字符' '(Space)
- 正负号+和-(Sign)
- 字符串型的数值(Number)
- 除以上三种情况外的任何情况(Other)
阶段分析
如果想要将字符串转换为整数,那么必然会经历这四个有序的阶段:
- 开始转换(start)
- 判断正负(signed)
- 生成数值(in_number)
- 结束转换(end)
梳理为表格形式
解决的问题:字符串转换整数 (atoi)
可以想到Javascript 的 parseInt(),使用这个API,进行尝试。
parseInt(string, radix):
string:要被解析的值。如果参数不是一个字符串,则将其转换为字符串。字符串开头的空白符将会被忽略。
radix(可选):需要转换的进制,介于 2 到 36。
返回值: 如果被解析参数的第一个字符无法被转化成数值类型,则返回NaN。
- 无视开头空格(√)
- 返回有符号整数(√)
- 无视整数部分后的字符(√)
- 范围在
32
位内(含)(x) - 其他情况返回
0
(x)
需要注意:
在使用parseInt(string, radix)这一API时,如果不传入radix参数,会有两种特殊情况:
如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制).
如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数,取决与ECMAScript的版本。
/** * @param {string} s * @return {number} */ var myAtoi = function(s) { const number = parseInt(s, 10); if(isNaN(number)) { return 0; } else if (number < Math.pow(-2, 31) || number > Math.pow(2, 31) - 1) { return number < Math.pow(-2, 31) ? Math.pow(-2, 31) : Math.pow(2, 31) - 1; } else { return number; } };
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现