LeetCode中字符串转换整数
在LeetCode中,字符串转换整数(String to Integer)是一个经典的算法题目。这个问题的基本思路是将一个字符串转换为相应的整数,如果字符串包含非数字字符,则返回0。此外,给定的字符串可能以“+”或“-”开头。
在这篇文章中,我们将解释如何使用Java解决这个问题,并提供一些示例和详细的代码实现。
- 判断前导空格
字符串转换整数的第一步是判断前导空格。这种情况下,我们可以使用Java内置的函数 trim(),它可以在字符串前和后删除所有空格。
示例:
String str = " a b c";
String trimmedStr = str.trim();
System.out.println(trimmedStr); // Output: "a b c"
- 判断正负号
接下来,我们需要判断字符串里面是否有一个正负号。如果有正负号,则将其作为字符串的第一个字符。如果字符串中没有这个符号,则默认为正数。
示例:
String str = "-42";
int sign = 1;
int start = 0;
if (str.charAt(0) == '-') {
sign = -1;
start++;
} else if (s.charAt(0) == '+') {
start++;
}
- 计算数字
接下来,我们需要从字符串中提取数字并把它们相加起来。可以通过使用10进制的公式来实现。
示例:
String str = " -42words ";
int result = 0;
for (int i = start; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
break;
}
int digit = str.charAt(i) - '0';
if (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && digit > 7)) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
result = result * 10 + digit;
}
return sign * result;
- 完整代码示例
class Solution {
public int myAtoi(String s) {
int sign = 1;
int start = 0;
int result = 0;
// 判断前导空格
s = s.trim();
// 判断正负号
if (s.charAt(0) == '-') {
sign = -1;
start++;
} else if (s.charAt(0) == '+') {
start++;
}
// 计算数字
for (int i = start; i < s.length(); i++) {
if (!Character.isDigit(s.charAt(i))) {
break;
}
int digit = s.charAt(i) - '0';
if (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && digit > 7)) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
result = result * 10 + digit;
}
return sign * result;
}
}
其他实现方式 ,优秀的代码示例:
class Solution {
public int myAtoi(String s) {
int sign = 1, len = s.length(), i = 0, ans = 0;
while (i < len && s.charAt(i) == ' ') ++i;
if (i < len && (s.charAt(i) == '+' || s.charAt(i) == '-')) {
sign = s.charAt(i++) == '+' ? 1 : -1;
}
while (i < len && Character.isDigit(s.charAt(i))) {
int digit = s.charAt(i++) - '0';
if (ans > (Integer.MAX_VALUE - digit) / 10) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
ans = ans * 10 + digit;
}
return sign * ans;
}
}
这段代码的思路与前面介绍的相同,但是它使用的是更简洁的代码逻辑和少量的变量。同时,它使用贪心算法并且避免了乘法运算,使得代码更为高效。
这里还有一个使用状态机(StateMachine)的Java代码示例:
class Solution {
public int myAtoi(String s) {
Automaton automaton = new Automaton();
int length = s.length();
for (int i = 0; i < length; ++i) {
automaton.get(s.charAt(i));
}
return (int) (automaton.sign * automaton.ans);
}
}
class Automaton {
public int sign = 1;
public long ans = 0;
private String state = "start";
private Map<String, String[]> table = new HashMap<String, String[]>() {{
put("start", new String[]{"start", "signed", "in_number", "end"});
put("signed", new String[]{"end", "end", "in_number", "end"});
put("in_number", new String[]{"end", "end", "in_number", "end"});
put("end", new String[]{"end", "end", "end", "end"});
}};
public void get(char c) {
state = table.get(state)[getCol(c)];
if ("in_number".equals(state)) {
ans = ans * 10 + c - '0';
ans = sign == 1 ? Math.min(ans, (long) Integer.MAX_VALUE) : Math.min(ans, -(long) Integer.MIN_VALUE);
} else if ("signed".equals(state)) {
sign = c == '+' ? 1 : -1;
}
}
private int getCol(char c) {
if (c == ' ') {
return 0;
}
if (c == '+' || c == '-') {
return 1;
}
if (Character.isDigit(c)) {
return 2;
}
return 3;
}
}
这个算法实现从状态机的角度考虑字符串的内容。它的优点是代码简洁,易于理解,并且易于扩展。同时,它的缺点是算法的效率有点低,其空间复杂度较高。
- 总结
在这篇文章中,我们讨论了如何使用Java解决字符串转换整数这个问题,并提供了相应的示例和详细的代码实现。使用这些代码,可以快速解决类似的题目以及其他一些字符串处理问题。