两道关于数字转换的题
一 java实现atoi()
* atoi()描述:
* 参数str字符串,如果第一个非空格字符存在,是数字或者正负号则开始做类型转换, 之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。否则,返回零。
下面是leetcode社区Discuss版面的两个解决方案:
方案1:
public static int myAtoi(String str) { int index = 0, sign = 1, total = 0; //1. 如果为空 if(str.length() == 0) return 0; //2. 移除前置空格 str = str.trim(); //3. 检查符号位 if(str.charAt(index) == '+' || str.charAt(index) == '-'){ sign = str.charAt(index) == '+' ? 1 : -1; index ++; } //4. 转换成数字并避免溢出 while(index < str.length()){ int digit = str.charAt(index) - '0'; if(digit < 0 || digit > 9) break;//如果该位符号不是0-9则停止转换 //检查加和数是否溢出 //check if total will be overflow after 10 times and add digit //如果溢出,正数返回Integer类型的最大值,附属返回Integer类型的最小值 //其中Integer.MAX_VALUE是Integer的最大值,Integer.MIN_VALUE是Integer的最小值 if(Integer.MAX_VALUE/10 < total || Integer.MAX_VALUE/10 == total && Integer.MAX_VALUE %10 < digit) return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; //没有溢出,则继续累加 total = 10 * total + digit; index ++; } return total * sign; }
方案2:
public static int myAtoi1(String str) { //判断非空 if (str == null || str.length() == 0) return 0; //去空格 str = str.trim(); char firstChar = str.charAt(0); int sign = 1, start = 0, len = str.length(); long sum = 0; if (firstChar == '+') { sign = 1; start++; } else if (firstChar == '-') { sign = -1; start++; } for (int i = start; i < len; i++) { if (!Character.isDigit(str.charAt(i))) return (int) sum * sign; sum = sum * 10 + str.charAt(i) - '0'; //判断溢出 if (sign == 1 && sum > Integer.MAX_VALUE) return Integer.MAX_VALUE; if (sign == -1 && (-1) * sum < Integer.MIN_VALUE) return Integer.MIN_VALUE; } return (int) sum * sign; }
其实二者的主要思路都是差不多的:
1 判断str是否为空,为空则返回0
2 去空格,用str.trim()能去掉str字符串前后的空格和换行等
3 判断字符类型(正负号)
4 循环取出数字并累加。跳出循环条件有三个:
①最新读取的字符不是0-9
②累加结果上溢出或者下溢出
③读取字符串完毕
二 翻转数字
反转数字的整数。
Example1: x = 123,return 321
Example2: x = -123,return -321
public int reverse(int x) { int result = 0; while (x != 0) { int tail = x % 10; int newResult = result * 10 + tail; if ((newResult - tail) / 10 != result) { return 0; } result = newResult; x = x / 10; } return result; }
下面是我自己编写的处理方法,存在溢出问题
public static int reverse(int x){ boolean sign = false; if(x<0){ sign = true; x = x*(-1); } int y = 0; for(int i=1; i<=x; i=i*10){ int z = (x%(i*10)); y = y*10 + z/i; } if(sign) y = y*(-1); return y; }
总结:两个放在一起主要原因是自己做这些题的时候会忽略溢出问题,注意溢出判断和Integer类型的应用