请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
函数 myAtoi(string s) 的算法如下:
- 读入字符串并丢弃无用的前导空格
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
- 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
- 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:
本题中的空白字符只包括空格字符 ' ' 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/string-to-integer-atoi
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
问题分析
需要思考如下几个问题。
输入有几种类型?哪一部分是我们需要处理的部分
- 数字
- 整数范围内
- 正整数
- 负整数
- 0
- 整数范围外
- 小于最小边界值
- 大于最大边界值
- 非数字
- 混合数组
- 前数字后子母
- 前字母后数字
- 中间数字
- 纯字母
根据题目进行分析:
我们需要处理的内容有
- 正负数和0
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
- 混合数字的前数字后字母
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
- 其他非数字类型输出0
将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)
- 整数范围之外输出边界值
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
综上我们将其流程总结为:
那么我们针对每个流程进行梳理
- 前导空格去除
从前往后遇到第一个非空格认为前导空格去除结束 - 正负号判定
去除空格判定结束后的下一个字符是非(-)号数字或者字母或者是一个(-)号 - 数字字符串提取
从正负号判定之后的第一个字符开始,遇到下一个非数字结束 - 数字字符串转化
- 在整数范围 [−231, 231 − 1] 内输出当前数字
- 在下边界之外,输出下边界值
- 在上边界之外,输出上边界值
- 结果输出
正常输出结果
第四步衍生子问题:
边界值如何判定是否超纲?
判定依据:- 长度大于32位
- 从左到右依次判定当前值是否小于边界值转换的字符串
则针对每一个小点我们可以写出代码
- 前导空格去除
private String replaceBlank(String s){
int i = 0;
for (char c : s.toCharArray()) {
if (c != ' '){
break;
}else {
i++;
}
}
return s.substring(i);
}
- 正负号判定
private boolean hasMinus(String c) {
if (c.charAt(0) == '-'){
return true;
}
return false;
}
- 数字字符串提取
private String extractionOfDigital(String rplString) {
StringBuilder builder = new StringBuilder();
rplString = replaceFirstZero(rplString);
// 去除前面的0
for (char c : rplString.toCharArray()) {
if (c >= '0' && c <= '9'){
builder.append(c);
}else {
break;
}
}
return builder.toString();
}
private String replaceFirstZero(String s){
int i = 0;
for (char c : s.toCharArray()) {
if (c == '0'){
i++;
}else {
break;
}
}
return s.substring(i);
}
- 数字字符串转化
private Integer convertsAStringToANumber(String numStr, boolean hasMinus) {
if (numStr.equals("")){
return 0;
}
if (numStr.length() > 10){
if (!hasMinus){
return Integer.MAX_VALUE;
}else {
return Integer.MIN_VALUE;
}
}
if (numStr.length() < 10){
if (hasMinus){
return Integer.valueOf("-"+numStr);
}else {
return Integer.valueOf(numStr);
}
}
if (hasMinus){
// 负数
String minValue = Integer.MIN_VALUE + "";
int i = 0;
char[] numStrC = ("-"+numStr).toCharArray();
boolean isGreaterThanThe = false;
for (char c : minValue.toCharArray()) {
char n = numStrC[i++];
if (n > c){
isGreaterThanThe = true;
break;
}else if (n < c){
break;
}
}
if (isGreaterThanThe){
return Integer.MIN_VALUE;
}else {
return Integer.valueOf("-"+numStr);
}
}else {
// 正数
String minValue = Integer.MAX_VALUE + "";
int i = 0;
char[] numStrC = numStr.toCharArray();
boolean isGreaterThanThe = false;
for (char c : minValue.toCharArray()) {
char n = numStrC[i++];
if (n > c){
isGreaterThanThe = true;
break;
}else if (n < c){
break;
}
}
if (isGreaterThanThe){
return Integer.MAX_VALUE;
}else {
return Integer.valueOf(numStr);
}
}
}
整体代码为:
public class Main {
public static void main(String[] args) {
new Main().test();
}
public void test(){
System.out.println(new Solution().myAtoi("1095502006p8"));
}
class Solution {
public int myAtoi(String s) {
if (s == null || s.equals("")){
return 0;
}
// 前导空格去除
String rplString = replaceBlank(s);
if (rplString.length() == 0){
return 0;
}
boolean hasMinus = hasMinus(rplString);
if (rplString.startsWith("-") ||rplString.startsWith("+")){
rplString = rplString.substring(1);
}
String numStr = extractionOfDigital(rplString);
Integer num = convertsAStringToANumber(numStr,hasMinus);
return num;
}
private Integer convertsAStringToANumber(String numStr, boolean hasMinus) {
if (numStr.equals("")){
return 0;
}
if (numStr.length() > 10){
if (!hasMinus){
return Integer.MAX_VALUE;
}else {
return Integer.MIN_VALUE;
}
}
if (numStr.length() < 10){
if (hasMinus){
return Integer.valueOf("-"+numStr);
}else {
return Integer.valueOf(numStr);
}
}
if (hasMinus){
// 负数
String minValue = Integer.MIN_VALUE + "";
int i = 0;
char[] numStrC = ("-"+numStr).toCharArray();
boolean isGreaterThanThe = false;
for (char c : minValue.toCharArray()) {
char n = numStrC[i++];
if (n > c){
isGreaterThanThe = true;
break;
}else if (n < c){
break;
}
}
if (isGreaterThanThe){
return Integer.MIN_VALUE;
}else {
return Integer.valueOf("-"+numStr);
}
}else {
// 正数
String minValue = Integer.MAX_VALUE + "";
int i = 0;
char[] numStrC = numStr.toCharArray();
boolean isGreaterThanThe = false;
for (char c : minValue.toCharArray()) {
char n = numStrC[i++];
if (n > c){
isGreaterThanThe = true;
break;
}else if (n < c){
break;
}
}
if (isGreaterThanThe){
return Integer.MAX_VALUE;
}else {
return Integer.valueOf(numStr);
}
}
}
private String extractionOfDigital(String rplString) {
StringBuilder builder = new StringBuilder();
rplString = replaceFirstZero(rplString);
// 去除前面的0
for (char c : rplString.toCharArray()) {
if (c >= '0' && c <= '9'){
builder.append(c);
}else {
break;
}
}
return builder.toString();
}
private String replaceFirstZero(String s){
int i = 0;
for (char c : s.toCharArray()) {
if (c == '0'){
i++;
}else {
break;
}
}
return s.substring(i);
}
private boolean hasMinus(String c) {
if (c.charAt(0) == '-'){
return true;
}
return false;
}
private String replaceBlank(String s){
int i = 0;
for (char c : s.toCharArray()) {
if (c != ' '){
break;
}else {
i++;
}
}
return s.substring(i);
}
}
}