字符串3:把字符串转换成整数

来源:互联网 发布:php转盘抽奖程序 编辑:程序博客网 时间:2024/05/16 15:20

题目:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

输入描述:输入一个字符串,包括数字字母符号,可以为空

输出描述:如果是合法的数值表达则返回该数字,否则返回0

输入例子:+2147483647  1a33  输出例子:  2147483647  0

思路:给定一个字符串,要求将这个字符串转换为正数,转换的基本思想很简单,首先将其转换为数组,遍历字符元素,对于每个字符,将其转换为对应的值,例如‘3’转换为3,转换方法很简单,由于字符char对应唯一的一个ascii码,而ascii码是整数,因此可以将其转化(常识:ascii码中0~9分别对应48~57,因此将char-48就转换为char字面的数值,如果不记得0对应48,那么可以直接用char参与运算char-‘0’得到的就是char的字面数值,此外a对应97,A对应65),在遍历时每次在前一个数值的基础上res*10+(char-‘0’)就得到当前的值。

本题的关键考察点是各种特殊情况的全面考虑,保证考虑周全。在优秀情况不明确时需要与面试官进行沟通。

①空输入:str==null或者str.length()<=0;此时直接返回0

在实际中,很多情况下非法输入要求也返回0,而如果正常输入的值是0,那么其返回值也应该是0,这是返回到底是因为值是0还是非法输入呢?这需要区分,在实际中使用一个全局变量valid来作为标记,如果是非法输入,那么返回0同时将valid设置为false;如果是正常的值0那么返回0而valid保持true,于是最终根据valid的值可以判断究竟是正常输入还是非法输入。本题中由于要求非法输入返回0所以直接返回0就可以了。

②输入的字符串含有非数字的字符,例如123a45,于是在遍历时,对于每一个字符要判断其是否在’0’~’9’(或者48~57)范围之内,如果不在就说明输入不合法直接返回0;

③输入的字符串带有符号,例如+123或者-123;于是在遍历之前先专门对第一个字符进行array[0]进行判断,看其是否是‘+’或者‘-’或者没有符号,这决定了最后的结果是否要乘以一个-1,以及如果有符号,则遍历相乘从index=1开始,如果没有符号则遍历相乘从index=0开始。

④输入的字符串只有一个符号例如‘+’或者‘-’

由于对于第一个字符array[0]单独考察,之后遍历的循环范围是i=1;i<length;i++显然不满足值为0,已经包含在上面的结果情况中了。

⑤字符串越界溢出的问题

如果字符串过长,例如str=”12345678987654321”,那么显然是溢出的,因此在遍历数组逐步相乘的过程中就应该每一步都检查一下当前result是否已经溢出,如果溢出则返回0表示不合法输入,并且最好能够抛出一个显示的异常。throw new RuntimeException("上溢出");

并且注意如果定义result为int,而以Integer.MAX_VALUE和Integer.MIN_VALUE作为溢出的比较值的话是错误的,因为某一时刻result在运算赋值时会突然溢出,因此如果设定字符串的转化范围是int,那么result应该使用long,这样才能防止溢出。

注意几点①:Java中==表示比较两个对象的地址是否相同,但是只有对于对象,==才是比较两个对象是否相同,对于基本类型,==依然是比较值是否相同,于是对于String,==是比较两个字符串的地址是否相同,同样值为”abc”的字符串,对象不同他们==为false,但是int,char是基本数据类型,==比较的是他们的值是否相同,因此这里可以使用==比较char是否相同。Char没有equals()方法。②对于整数int,long都是有范围的,他的范围可以自己记住是-2^(8*4-1)~2^(8*4-1)-1即为-2^31~2^31-1或者直接调用方法Integer.MAX_VALUE和Integer.MIN_VALUE来求出范围。③异常抛出之后方法自动结束返回,之后的代码不会再执行,因此在throw异常都为后面的return语句不会得到执行,是编译错误。即异常抛出后程序方法终止,但是try/catch后如果异常捕获则程序继续,这就是try/catch的意义。

//将一个字符串转化为正数int输出,考察的是对特殊情况、边界情况的考虑全面性public class Solution {    public int StrToInt(String str) {        //特殊输入        if(str==null||str.length()<=0) return 0;                //将字符串转化为数组        char[] array=str.toCharArray();                        //根据有无+-符号来决定计算值时的起始元素位置        int numberIndex=0;                //表示当前的转换结果,注意,为了避免溢出要使用更高一级的类型        long result=0;//①常识:字符char不能使用equals方法,char是基本数据类型,与String不同,它的==也是用来比较值        if('+'==array[0]){            numberIndex=1;        }else if('-'==array[0]){            numberIndex=1;        }else{            //说明没有+-号,则从0开始计算数值            numberIndex=0;        }                //遍历非符号的字符,进行结果统计        for(int i=numberIndex;i<array.length;i++){            //判断字符是否是数字            if(array[i]>='0'&&array[i]<='9'){                result=result*10+(array[i]-'0');                //②判断当前结果是否溢出了int的范围,向上溢出必然是正数,于是array[0]=’+’                if(array[0]=='+'&&result>Integer.MAX_VALUE){                    //向上溢出                    //throw new RuntimeException("向上溢出");                    //③抛出异常自动终止程序,可以不返回                    return 0;   //向上溢出必然是负数,于是array[0]=’-’                }else if(array[0]=='-'&&result<Integer.MIN_VALUE){                    //向下溢出                    //throw new RuntimeException("向下溢出");                    return 0;                }            }else{                return 0;            }        }                        if(array[0]=='-'){         //由于result是long类型,返回值是int类型,因此在返回时需要强转为int  return (int)(result*(-1));       }else{           return (int)result;       }    }}


0 0
原创粉丝点击