JAVA解法
class Solution {
public int myAtoi(String s) {
// 将传进来的字符串转换为字符数组
char[] chars = s.toCharArray();
// 获取字符数组的长度
int n = chars.length;
// 定义全局索引起始位置
int idx = 0;
while (idx < n && chars[idx] == ' ') {
// 去掉空格
idx++;
}
if (idx == n) {
//去掉所有空格后若到了末尾则停止程序
return 0;
}
// 标记是否为负
boolean negative = false;
if (chars[idx] == '-') {
//遇到负号,则标记为负
negative = true;
// 继续下一个
idx++;
} else if (chars[idx] == '+') {
// 遇到正号,则直接下一个
idx++;
} else if (!Character.isDigit(chars[idx])) {
// 若第一个就遇到非数字非正负符号的其他字符则停止程序
return 0;
}
// 定义一个存储最终结果的变量
int ans = 0;
// 数组下标不越界且字符为数字时进行遍历
while (idx < n && Character.isDigit(chars[idx])) {
// 由于字符 '0' 到 '9' 的 ASCII 值连续,通过字符的 ASCII 值作差即可巧妙转换为字符对应的整数值
int digit = chars[idx] - '0';
// 每一次循环都要防止数值过大导致溢出,要判断 ans * 10 + digit 是否大于 Integer.MAX_VALUE,但是直接 ans * 10 + digit 的话可能在此直接溢出,所以为了避免运算时溢出,将等式移位,将乘变成除
if (ans > (Integer.MAX_VALUE - digit) / 10) {
// 如果上面判断该数为负数的话,返回 Integer.MIN_VALUE,为正的话返回,Integer.MAX_VALUE
return negative? Integer.MIN_VALUE : Integer.MAX_VALUE;
}
// 由于遍历是从左向右遍历的,因此只需要每次用 ans 乘以 10 并加上当前的值即可还原数对应的值
ans = ans * 10 + digit;
// 下一个
idx++;
}
// 返回最终结果,若为正则返回正数,若为负则返回负数
return negative? -ans : ans;
}
}
题解分析
根据题目的要求,这道题就是要提取传进来的字符串中的数并转化为其对应的值,题目告知目标数字可能存在正负符号,且字符串存在空格以及非数字的其他字符。
首先我们将传进来的字符串拆成一个一个的字符存到字符数组中,并记录其数组长度,定义全局索引起始位置为 0, 接着我们用 while 循环将所有前置空格去掉(跳过),去掉空格后判断全局索引的位置,假如全局索引的位置来到了字符串末尾,则说明字符串纯空格,终止程序执行。
假如全局索引的位置小于字符串的末尾位置则往下执行,先定义一个布尔值来标记目标数是否为负数,默认为 false,是负数则为 true 否则为 false。此时,截取当前全局索引所在位置的字符判断是否是负号、正号或其他非数字字符,假如是负号,则将布尔值置为 true,并移动全局索引到下一个字符所在位置,假如为正号,则直接下一个位置(无符号默认为正),假设为其他非数字字符则直接终止程序运行。
先定义一个存储最终结果的变量,若符号位后的字符是数字字符(或者第一个字符不是符号位且为数字字符),则进入循环,在数组长度的边界内,将所有得到的数字字符(‘0’-‘9’)分别与 字符 0 即 ‘0’ 作差,由于字符 ‘0’ 到 ‘9’ 的 ASCII 值连续,通过字符的 ASCII 值作差即可巧妙转换为字符对应的整数值,每一次循环都要防止数值过大导致溢出,要判断 ans * 10 + digit
是否大于Integer.MAX_VALUE
,但是直接 ans * 10 + digit
的话可能在此直接溢出,所以为了避免运算时溢出,将等式移位,将乘变成除。
如果大于了整数最大值则依据该数的正负返回整数最大值或整数的最小值,假如运算时不超出整数最大值的话,则继续往下累加最终结果,由于遍历是从左向右遍历的,因此只需要每次用 ans 乘以 10 并加上当前的值即可还原数对应的值,继续移动全局索引直到等于数组长度时跳出循环,依据目标数的正负返回最终结果即可。
leetcode原题:8. 字符串转换整数 (atoi)
评论区