每日一题 为了工作 2020 0409 第三十八题
/**
*
* 问题:将整数字符串转换成整数值
* 给定一个字符串 string, 如果 string符合日常书写的整数形式, 并且属于32位整数的范围,
* 返回 string所代表的整数值, 否则返回 0。
* 举例:
* string=" 123", 返回123。
* string="023", 因为'023"不符合日常的书写习惯, 所以返回0。
* string="A13", 返回 0。
* string="0", 返回 0。
* string="2147483647", 返回2147483647。
* string="2147483648", 因为溢出了, 所以返回0。
* string="-123", 返回-123。
*
* 分析:
* 首先检查 string是否是符合日常书写的整数形式, 具体判断如下:
* 1. 如果 string不以"-"开头, 也不以数字字符开头, 例如, string=="A12",则返回 false。
* 2. 如果 string以"-"开头。但是 string的长度为 1, 即 string=="-", 返回 false。如果
* string的长度大于 1, 但是"-"的后面紧跟着 "0",例如 string=="-0"或"-012",返回 false。
* 3. 如果string以"0"开头, 但是string的长度大千 1, 例如 string=="023",返回 false。
* 4. 如果经过步骤1-步骤3都没有返回, 接下来检查str[1 ..N-1]是否都是数字字符,如果有一个不是
* 数字字符,返回 false。如果都是数字字符,说明 string符合日常书写,返回 true。
*
* 如果 string不符合日常书写的整数形式, 根据题目要求, 直接返回 0即可。如果符合, 则进行如下转换过程:
* 1.生成 4个变量。布尔型常量 posi, 表示转换的结果是负数还是非负数, 这完全由str开头的字符决定, 如
* 果以"-"开头, 那么转换的结果一定是负数, 则 posi为 false,否则 posi为 true。整型常量 minq,
* minq等于 Integer.MIN_VALUE/1O, 即32位整数最小值除以10得到的商,整型常量 minr, minr
* 等于Integer.MIN_YALUE%10, 即32位整数最小值除以10得到的余数。整型变量 res,转换的结果,
* 初始时res=O。
* 2.32位整数的最小值为-2147483648, 32位整数的最大值为2147483647。可以看出,最小值的绝对值比
* 最大值的绝对值大1,所以转换过程中的绝对值一律以负数的形式出现,然后根据 posi决定最后返回什么。比
* 如 string="123",转换完成后的结果是-123,posi=true,所以最后返回 123。再如string="-123",
* 转换完成后的结果是-123, posi=false, 所以最后返回-123。比如 string="-2147483648",转
* 换完成后的结果是-2147483648, posi = false, 所以最后返回的结果是 2147483648。再比如 说
* string="2147483648",转换完成后的结果是2147483648, posi=true, 此时发现-2147483648
* 变成2147483648会产生溢出,所以返回 0。也就是说, 既然负数比正数拥有更大的绝对值范围, 那么转换过程
* 中一律以负数的形式记录绝对值, 最后再决定返回的数到底是什么。
* 3.如果 string以‘-’开头, 从 string[1]开始从左往右遍历 string, 否则从string[O]开始从左往右遍
* 历 string。举例说明转换过程, 比如 string="123", 遍历到 1时, res=res*10+(-1)==-1,遍历
* 到'2'时,res=res*10+(-2)=-12, 遍历到 '3'时, res=res*10+(-3)==-123。又比如说当遍历的
* string="-123", 字符‘-’跳过,从字符 '1'开始遍历,res=res*1O+(-1)=-1,遍历到'2'时,
* res=res*10+(-2)=-12, 遍历到'3'时,res=res* 10+(-3)=-123。遍历的过程中如何判断 res已
* 经溢出了?假设当前字符为 a, 那么'0'-a就是当前字符所代表的数字的负数形式, 记为 cur。如果在 res加上
* cur之前,发现 res已经小于 minq, 那么当 res加上cur之后一定会溢出, 比如 string="3333333333",
* 遍历完倒数第一个字符后, res==-333333333 < minq=-214748364, 所以当遍历到最后一个字符时,
* res*10肯定会产生溢出。如果在 res加上cur之前, 发现 res等于 minq, 但又发现 cur小于minr,那么当
* res加上cur之后一定会溢出, 比如 string="2147483649", 遍历完倒数第二个字符后,res=-214748364 == minq,
* 当遍历到最后一个字符时发现有res==minq, 同时也发现cur==-9 < minr==-8, 那么当 res加上cur之后
* 一定会溢出。出现任何一种溢出清况时,直接返回0。
* 4.遍历后得到的res根据posi 的符号决定返回值。如果posi为true, 说明结果应该返回正, 否则说明应该返回负。
* 如果res正好是32位整数的最小值, 同时又有 posi为 true,说明溢出, 直接返回0。
*
* @author 雪瞳
*
*/
public class Convert {
public boolean isValid(char string[]){
if(string[0] !='-' &&(string[0] <'0'||string[0]>'9')){
return false;
}
if(string[0] == '-' &&(string.length == 1 || string[1]=='0')){
return false;
}
if(string[0]=='0'&&string.length>1){
return false;
}
for(int i = 1;i<string.length;i++){
if(string[i]<'0'||string[i]>'9'){
return false;
}
}
return true;
}
public int convert(String string){
if(string == null || string.equals("")){
return 0;
}
char charString[] = string.toCharArray();
boolean flag = isValid(charString);
if(flag==false){
return 0;
}
//负数 posi为 false
boolean posi = charString[0]=='-'?false:true;
int minq = Integer.MIN_VALUE/10;
int minr = Integer.MIN_VALUE%10;
int res = 0;
int cur = 0;
for(int i= posi?0:1;i<charString.length;i++){
cur ='0'-charString[i];
if((res<minq)||(res==minq&&cur<minr)){
return 0;
}
res = res*10+cur;
}
//正数过界
if(posi && res==Integer.MIN_VALUE){
return 0;
}
return posi?-res:res;
}
}