- 标签:字符串处理、整数转换
题目描述
请你来实现一个 myAtoi(string s)
函数,使其能将字符串转换成一个整数。
函数 myAtoi(string s)
的输入参数为一个字符串 s
,你需要根据这个字符串转换并返回一个整数。如果转换失败,则返回 0。
示例:
输入: "42"
输出: 42
输入: " -42"
输出: -42
输入: "4193 with words"
输出: 4193
输入: "words and 987"
输出: 0
输入: "-91283472332"
输出: -2147483648 (即 INT_MIN,因为 -91283472332 小于 INT_MIN)
说明:
假设我们的环境只能存储 32 位大小的有符号整数,其数值范围是 [-2^31, 2^31 - 1]。如果数值超过这个范围,请返回 INT_MAX (2^31 - 1) 或 INT_MIN (-2^31)。
思路及实现
我们将分别使用 Java、C、Python3 和 Golang 来实现这个功能。
方式一:利用正则表达式和基础算法
思路
- 去除空格:首先去除字符串前面的空白字符。
- 正则表达式匹配:使用正则表达式匹配可能的整数部分(包括正负号)。
- 转换与边界检查:将匹配到的字符串转换为整数,并进行边界检查。
Java 版本
public class Solution {
public int myAtoi(String s) {
s = s.trim(); // 去除空格
// 正则表达式匹配整数部分
Pattern pattern = Pattern.compile("^([+\\-]?\\d+).*$");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
String numStr = matcher.group(1);
try {
long num = Long.parseLong(numStr);
if (num > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (num < Integer.MIN_VALUE) return Integer.MIN_VALUE;
return (int) num;
} catch (NumberFormatException e) {
return 0;
}
}
return 0;
}
}
C 语言版本
由于 C 语言没有内置的正则表达式处理功能,这里我们简化处理,不采用正则表达式。
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int myAtoi(char *s) {
int sign = 1;
long long result = 0;
int i = 0;
// Skip whitespaces
while (s[i] == ' ') {
i++;
}
// Handle signs
if (s[i] == '-' || s[i] == '+') {
sign = (s[i++] == '-') ? -1 : 1;
}
// Process digits
while (isdigit(s[i])) {
result = result * 10 + (s[i] - '0');
if (sign == 1 && result > INT_MAX) {
return INT_MAX;
}
if (sign == -1 && -result < INT_MIN) {
return INT_MIN;
}
i++;
}
return (int)(sign * result);
}
Python3 版本
import re
def myAtoi(s: str) -> int:
s = s.strip() # 去除空格
match = re.match(r'^([+\-]?\d+).*$', s)
if match:
num_str = match.group(1)
num = int(num_str)
MAX_INT = 2147483647
MIN_INT = -2147483648
num = max(min(num, MAX_INT), MIN_INT)
return num
return 0
Golang 版本
在 Go 语言中,我们同样可以实现一个 myAtoi
函数,如下所示:
package main
import (
"fmt"
"math"
"strings"
"unicode"
)
func myAtoi(s string) int {
s = strings.TrimSpace(s) // 去除空格
sign := 1
if len(s) == 0 {
return 0
}
// 判断符号
if s[0] == '+' || s[0] == '-' {
if s[0] == '-' {
sign = -1
}
s = s[1:]
}
result := 0
for _, ch := range s {
if !unicode.IsDigit(ch) {
break
}
digit := int(ch - '0')
if result > math.MaxInt32/10 || (result == math.MaxInt32/10 && digit > 7) {
if sign == 1 {
return math.MaxInt32
}
return math.MinInt32
}
result = result*10 + digit
}
return sign * result
}
func main() {
fmt.Println(myAtoi("42")) // 输出: 42
fmt.Println(myAtoi(" -42")) // 输出: -42
fmt.Println(myAtoi("4193 with words")) // 输出: 4193
fmt.Println(myAtoi("words and 987")) // 输出: 0
fmt.Println(myAtoi("-91283472332")) // 输出: math.MinInt32 (-2147483648)
}
复杂度分析
- 时间复杂度:O(n),其中 n 是字符串
s
的长度。我们需要遍历整个字符串来确定整数的值。 - 空间复杂度:O(1)。我们只使用了固定数量的变量,没有使用与输入大小成比例的空间。
方式二:逐步迭代(不使用正则表达式)
对于方式二,我们可以不使用正则表达式,而是直接通过迭代字符串中的每个字符来转换整数。这种方法通常比使用正则表达式更快,因为正则表达式引擎本身有一定的开销。
由于方式一的 C 语言实现已经采用了逐步迭代的方法,这里就不再重复提供方式二的 C 语言代码。对于 Java、Python3 和 Golang,可以通过类似的逻辑来实现,即逐个检查字符,累积数字,并处理边界情况。
总结
方式 | 优点 | 缺点 | 时间复杂度 | 空间复杂度 |
---|---|---|---|---|
方式一(正则) | 代码简洁,易于理解和实现 | 正则表达式可能带来性能开销 | O(n) | O(1) |
方式二(迭代) | 性能较好,没有正则表达式开销 | 代码可能相对较长,需要手动处理更多情况 | O(n) | O(1) |
相似题目
相似题目 | 难度 | 链接 |
---|---|---|
字符串转换为整数 (atoi) 的扩展实现 | 中等 | LeetCode 8. String to Integer (atoi) |
有效的数字 | 困难 | LeetCode 65. Valid Number |
欢迎一键三连(关注+点赞+收藏),技术的路上一起加油!!!代码改变世界
关于我:阿里非典型程序员一枚 ,记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法(公众号同名),回复暗号,更能获取学习秘籍和书籍等
—⬇️欢迎关注下面的公众号:
进朱者赤
,认识不一样的技术人。⬇️—