public class Solution {
// 实现字符串到整数的转换,遵循atoi函数的规则
public int myAtoi(String s) {
// 如果输入字符串为空或长度为0,则直接返回0
if (s == null || s.length() == 0) {
return 0;
}
// 去除字符串两端的空格
s = s.trim();
// 如果去除空格后字符串为空,则直接返回0
if (s.length() == 0) {
return 0;
}
// 初始化符号位,默认为正数
int sign = 1;
// 初始化索引,用于遍历字符串
int index = 0;
// 处理正负号
if (s.charAt(index) == '-') {
sign = -1; // 负数
index++; // 移动到下一个字符
} else if (s.charAt(index) == '+') {
index++; // 如果是正号,也移动到下一个字符,因为正号是可选的
}
// 初始化结果为0
int result = 0;
// 遍历字符串,直到遇到非数字字符或字符串结束
while (index < s.length() && Character.isDigit(s.charAt(index))) {
// 将当前字符转换为数字
int digit = s.charAt(index) - '0';
// 检查是否超出int范围
// 注意:这里要同时考虑当前结果乘以10后是否会溢出,以及加上当前数字后是否会溢出
if (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && digit > 7)) {
// 如果超出正数范围,则返回最大正整数或最小负整数(根据符号位)
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
if (result < Integer.MIN_VALUE / 10 || (result == Integer.MIN_VALUE / 10 && digit > 8)) {
// 注意:虽然Java的int是补码表示,但这里为了简化逻辑,我们直接返回最小负整数
// 因为在Java中,Integer.MIN_VALUE的下一个更小的数会溢出到Integer.MAX_VALUE,但这不符合atoi的规范
return Integer.MIN_VALUE;
}
// 更新结果
result = result * 10 + digit;
index++;
}
// 返回最终结果,考虑符号位
return result * sign;
}
// 主函数,用于测试myAtoi方法
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.myAtoi(" -42")); // 输出: -42
System.out.println(solution.myAtoi("words and 987")); // 输出: 0
System.out.println(solution.myAtoi("-91283472332")); // 输出: -2147483648 (因为超出了int的范围)
}
}
注意:在原始代码中,对于超出int
范围的处理只考虑了正数的情况。我添加了对负数范围的检查,但实际上在Java中,由于int
是补码表示,且Integer.MIN_VALUE
没有直接的“下一个更小的数”(因为Integer.MIN_VALUE - 1
会溢出到Integer.MAX_VALUE
),所以通常我们不需要显式地检查负数溢出,因为一旦result
小于Integer.MIN_VALUE / 10
,任何合法的digit
(0-9)加上去都会导致溢出。然而,为了代码的完整性和清晰性,我还是保留了这部分注释和逻辑。但在实际执行中,只需要检查正数范围溢出即可,因为负数范围溢出在Java的int
表示中会自动处理(尽管结果不是预期的负数,但符合Java的溢出行为)。