1、题目名称
String to Integer (atoi) (字符串到数字的转换)
2、题目地址
https://leetcode.com/problems/string-to-integer-atoi/
3、题目内容
英文:Implement atoi to convert a string to an integer.
中文:实现atoi函数,将输入的字符串(String类型)转换为整型数据(Integer类型)
提示:实现的atoi函数需要满足以下特征
-
忽略字符串第一个非空格字符前的所有空格(whitespace),第一个非空格字符可以是正负号,后面接纯数字,atoi函数将这些纯数字转换为整型并返回
-
在数字字符后面可以接其他任何字符,但这些非数字的字符将被忽略
-
如果字符串中第一个非空格字符不是一个数字,字符串为空或仅由空格组成,则不对之进行转换
-
如果无法对字符串进行转换,返回0。如果取值过大或过小,返回整型数字的最大值INT_MAX(2147483647)或最小值INT_MIN(-2147483648)
4、解题方法1
可以使用Java中的Integer.parseInt函数解决问题,但Integer.parseInt函数与题目中描述的atoi在接收的输入上条件更为苛刻,因此需要将输入的字符串先转换为Integer.parseInt可以转换的形式(即将纯数字和前面的正负号先提取出来,再调用Integer.parseInt)。另外,在数值转换过程中,需要对弹出的异常信息进行判断,如果是因为溢出导致的NumberFormatException,则返回整型数字的最大或最小值,否则按无法转换处理,直接返回0。
Java代码如下:
/**
* 功能说明:LeetCode 8 - String to Integer (atoi)
* 开发人员:Tsybius2014
* 开发时间:2015年7月31日
*/
public class Solution {
/**
* Atoi函数
* @param str
* @return
*/
public int myAtoi(String str) {
//输入为空直接返回0
if (str.isEmpty()) {
return 0;
}
str = str.trim();
char[] array = str.toCharArray();
//判断数字的正负
boolean sign = true;
if (array[0] == '-') {
sign = false;
}
//字母第一次出现时,忽略后面的字符
int index = -1;
int signcount = 0;
for(int i = 0; i < array.length; i++) {
if (array[i] >= '0' && array[i] <= '9') {
continue;
} else if (array[i] == '-' || array[i] == '+') {
signcount++;
//正负号第二次出现时,忽略后面的字符
if (signcount > 1) {
index = i;
break;
}
continue;
} else {
index = i;
break;
}
}
//截取字符串
if (index != -1) {
str = str.substring(0, index);
//截取后为空串或无效串的,返回0
if (str.isEmpty() || str.equals("-") || str.equals("+")) {
return 0;
}
}
//数值转换
int result;
try
{
result = Integer.parseInt(str);
return (int)result;
}
catch (NumberFormatException ex) //数值溢出的情况
{
if (sign) {
return Integer.MAX_VALUE;
} else {
return Integer.MIN_VALUE;
}
}
catch (Exception ex) //其他异常
{
return 0;
}
}
}
5、解题方法2
方法2是方法1的另一种实现形式,因为方法1中采用了比较原始的方法对字符串解析,因此我想到了可以用正则表达式直接匹配出这个数字,交给Integer.parseInt函数。
Java代码如下:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* 功能说明:LeetCode 8 - String to Integer (atoi)
* 开发人员:Tsybius2014
* 开发时间:2015年7月31日
*/
public class Solution {
/**
* Atoi函数
* @param str
* @return
*/
public int myAtoi(String str) {
str = str.trim();
//正则匹配
Pattern p = Pattern.compile("^([+-]|)[0-9]+");
Matcher m = p.matcher(str);
if (m.find()) {
str = str.substring(m.start(), m.end());
} else {
return 0;
}
//判断数字的正负号
boolean sign = true;
if (str.charAt(0) == '-') {
sign = false;
}
//数值转换
int result;
try
{
result = Integer.parseInt(str);
return (int)result;
}
catch (NumberFormatException ex) //数值溢出的情况
{
if (sign) {
return Integer.MAX_VALUE;
} else {
return Integer.MIN_VALUE;
}
}
catch (Exception ex) //其他异常
{
return 0;
}
}
}
6、解题方法3
如果说上面两种方法是比较偷懒的办法,那第三种方法可以被称为“正规解法”,纯手工解析字符串。需要注意的是,在计算过程中,结果需要暂时存在一个长整型(Long)类型的数据中,这样可以在判断是否会有相同情况下整型溢出的情况,进而返回正确的返回值(Integer.MAX_VALUE或Integer.MIN_VALUE)。
Java代码如下:
/**
* 功能说明:LeetCode 8 - String to Integer (atoi)
* 开发人员:Tsybius2014
* 开发时间:2015年7月31日
*/
public class Solution {
/**
* 自制Atoi函数
* @param str 待转换字符串
* @return 转换后的数字
*/
public int myAtoi(String str) {
str = str.trim();
int sign = 0; //符号:0无符号、1正、2负
long result = 0; //计算结果
for (char ch : str.toCharArray()) {
if (ch == '+') {
//第一次遇到符号记录,第二次遇到符号忽略
if (sign != 0) {
break;
}
sign = 1;
} else if (ch == '-') {
if (sign != 0) {
break;
}
sign = -1;
} else if (ch >= '0' && ch <= '9') {
//遇到数字,还要检查是否超过了整型的最大值
result *= 10;
result += (ch - '0');
if (result > Integer.MAX_VALUE) {
if (sign >= 0) {
return Integer.MAX_VALUE;
} else {
return Integer.MIN_VALUE;
}
}
} else {
//遇到其他字符直接退出循环
break;
}
}
if (sign >= 0) {
return (int)result;
} else {
return (int)-result;
}
}
}
END