原题目:
Implement atoi to convert a string to an integer.
实现atoi函数,即将字符串转化为整数
算法分析:
函数首先丢弃所需的空格字符,直到找到第一个非空格字符。然后,从该字符开始,采用可选的初始加号或减号,后跟尽可能多的数字,并将其解释为数值。
字符串可以包含在形成整数数字之后的附加字符,这些字符被忽略,并且对此函数的行为没有影响。
如果str中的非空格字符的第一个序列不是有效的整数,或者如果没有这样的序列,因为str是空的或者它只包含空格字符,则不执行转换。
如果不能执行有效的转换,则返回零值。如果正确的值超出可表示值的范围,则返回INT_MAX(2147483647)或INT_MIN(-2147483648)。
遇到问题及解决方法:
1.如果字符串前几位为空字符,则应该先判断并丢弃
2.判断字符串中的+-号,并输出相应的正负值
3.如果字符串中间出现空格或其他字符,则不执行转换,直接退出
4.注意判断数值越界,输出应为整数的最大值和最小值之间
错误代码:
错误1:Wrong answer 没有判断在字符串中间出现非法字符的情况
public int myAtoi(String str){
if(str == null || str.length() < 1){
return 0;
}
//int i = 1;
String tmp = str.replaceAll(" ", "");
char first = tmp.charAt(0);
/*while(first == ' '){
first = str.charAt(i);
i++;
System.out.println("i=" + i + "first=" + first);
}*/
if(first == '-'){
return parseString(tmp,1,false);
}else if(first == '+'){
return parseString(tmp,1,true);
}else if(first <='9' && first >= '0'){
return parseString(tmp,0,true);
}else {
return 0;
}
}
public boolean isDigit(char c){
return c >= '0'&&c <= '9';
}
public int parseString(String str,int index,boolean positive){
if(index >= str.length()){
return 0;
}
int result;
long tmp = 0;
while(index < str.length()&&isDigit(str.charAt(index))){
tmp = tmp*10 + str.charAt(index) - '0';
if(tmp > 0x8000_0000L){
return Integer.MAX_VALUE;
}
index++;
}
if(positive){
if(tmp >= 0x8000_0000L){
return Integer.MAX_VALUE;
}else if(tmp == 2147483648L){
result = (int)(tmp - 1);
}else{
result = (int)tmp;
}
}
else{
if(tmp == 0x8000_0000L){
return result = 0x8000_0000;
}
else{
result = (int)-tmp;
}
}
return result;
}
错误2:整数越界
LeetCode提交源码:
public int myAtoi(String str){
int num = 0;
int sign = 1;
final int n = str.length();
if(n == 0)
return 0;
int i = 0; //i指向字符串的每一个字符
while(i < n && str.charAt(i) == ' ') //判断是否为空字符串,去除空字符串
i++;
if(str.charAt(i) == '+'){
i++;
}
else if(str.charAt(i) == '-'){
sign = -1; //判断正负数的符号位
i++;
}
for(; i < n; i++){
if(str.charAt(i) < '0' || str.charAt(i) > '9') //只要在字符串中间出现非数字,则直接中断退出循环
break;
if(num > Integer.MAX_VALUE / 10 ||
(num == Integer.MAX_VALUE / 10 &&
(str.charAt(i) - '0') > Integer.MAX_VALUE%10)){ //和10取余,就是判断2147483648和2147483647这两个数
return sign == -1?Integer.MIN_VALUE:Integer.MAX_VALUE;
}
num = num * 10 + str.charAt(i) - '0'; //-'0'实现了将字符转化为数字
}
return num*sign;
}
完整运行程序:
/**************************************************************
* Copyright (c) 2016
* All rights reserved.
* 版 本 号:v1.0
* 题目描述: String to Integer (atoi)
* mplement atoi to convert a string to an integer.
* 实现atoi函数,将字符串转化为数字
* 输入描述:请输入一个字符串:
* 2147483649
* 程序输出: 算法1转化结果为:
* 2147483647
* 算法2转化结果为:
* 2147483647
* 问题分析:1.如果字符串前几位为空字符,则应该先判断并丢弃
* 2.判断字符串中的+-号,并输出相应的正负值
* 3.如果字符串中间出现空格或其他字符,则不执行转换,直接退出
* 4.注意判断数值越界,输出应为整数的最大值和最小值之间
* 算法描述:函数首先丢弃所需的空格字符,直到找到第一个非空格字符。然后,从该字符开始,采用可选的初始加号或减号,
* 后跟尽可能多的数字,并将其解释为数值。
* 字符串可以包含在形成整数数字之后的附加字符,这些字符被忽略,并且对此函数的行为没有影响。
* 如果str中的非空格字符的第一个序列不是有效的整数,或者如果没有这样的序列,
* 因为str是空的或者它只包含空格字符,则不执行转换。
* 如果不能执行有效的转换,则返回零值。如果正确的值超出可表示值的范围,
* 则返回INT_MAX(2147483647)或INT_MIN(-2147483648)。
* 完成时间:2016-11-16
***************************************************************/
package org.GuoGuoFighting.LeetCode08;
import java.util.Scanner;
/*
算法1没有考虑在字符串中间出现非法字符的情况,其他情况则可以正常运行
*/
class SolutionMethod1{
public int myAtoi(String str){
if(str == null || str.length() < 1){
return 0;
}
//int i = 1;
String tmp = str.replaceAll(" ", "");
char first = tmp.charAt(0);
/*while(first == ' '){
first = str.charAt(i);
i++;
System.out.println("i=" + i + "first=" + first);
}*/
if(first == '-'){
return parseString(tmp,1,false);
}else if(first == '+'){
return parseString(tmp,1,true);
}else if(first <='9' && first >= '0'){
return parseString(tmp,0,true);
}else {
return 0;
}
}
public boolean isDigit(char c){
return c >= '0'&&c <= '9';
}
public int parseString(String str,int index,boolean positive){
if(index >= str.length()){
return 0;
}
int result;
long tmp = 0;
while(index < str.length()&&isDigit(str.charAt(index))){
tmp = tmp*10 + str.charAt(index) - '0';
if(tmp > 0x8000_0000L){
return Integer.MAX_VALUE;
}
index++;
}
if(positive){
if(tmp >= 0x8000_0000L){
return Integer.MAX_VALUE;
}else if(tmp == 2147483648L){
result = (int)(tmp - 1);
}else{
result = (int)tmp;
}
}
else{
if(tmp == 0x8000_0000L){
return result = 0x8000_0000;
}
else{
result = (int)-tmp;
}
}
return result;
}
}
class SolutionMethod2{
public int myAtoi(String str){
int num = 0;
int sign = 1;
final int n = str.length();
if(n == 0)
return 0;
int i = 0; //i指向字符串的每一个字符
while(i < n && str.charAt(i) == ' ') //判断是否为空字符串,去除空字符串
i++;
if(str.charAt(i) == '+'){
i++;
}
else if(str.charAt(i) == '-'){
sign = -1; //判断正负数的符号位
i++;
}
for(; i < n; i++){
if(str.charAt(i) < '0' || str.charAt(i) > '9') //只要在字符串中间出现非数字,则直接中断退出循环
break;
if(num > Integer.MAX_VALUE / 10 ||
(num == Integer.MAX_VALUE / 10 &&
(str.charAt(i) - '0') > Integer.MAX_VALUE%10)){ //和10取余,就是判断2147483648和2147483647这两个数
return sign == -1?Integer.MIN_VALUE:Integer.MAX_VALUE;
}
num = num * 10 + str.charAt(i) - '0'; //-'0'实现了将字符转化为数字
}
return num*sign;
}
}
public class StringtoInteger {
public static void main(String[] args){
System.out.println("请输入一个字符串:");
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
scanner.close();
SolutionMethod1 solution1 = new SolutionMethod1();
System.out.println("算法1转化结果为:");
System.out.println(solution1.myAtoi(str));
SolutionMethod2 solution2 = new SolutionMethod2();
System.out.println("算法2转化结果为:");
System.out.println(solution2.myAtoi(str));
}
}
程序运行结果:
算法1错误的运行结果: