每日一题 为了工作 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;
	}	
}

  

原文地址:https://www.cnblogs.com/walxt/p/12666222.html