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

      

  • 相关阅读:
    BZOJ 2064: 分裂( 状压dp )
    BZOJ 2096: [Poi2010]Pilots( set )
    BZOJ 3444: 最后的晚餐( )
    BZOJ 3156: 防御准备( dp + 斜率优化 )
    BZOJ 1770: [Usaco2009 Nov]lights 燈( 高斯消元 )
    BZOJ 2466: [中山市选2009]树( 高斯消元 )
    BZOJ 1316: 树上的询问( 点分治 + 平衡树 )
    codevs 1074
    bzoj 1015
    bzoj 1798
  • 原文地址:https://www.cnblogs.com/walxt/p/12666222.html
Copyright © 2020-2023  润新知