数据结构与算法分析笔记与总结(java实现)--字符串3:把字符串转换成整数

题目:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为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输出,考察的是对特殊情况、边界情况的考虑全面性

publicclass 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(inti=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 newRuntimeException("向上溢出");

                    //③抛出异常自动终止程序,可以不返回

                    return 0;

                              //向上溢出必然是负数,于是array[0]=’-’

                }elseif(array[0]=='-'&&result<Integer.MIN_VALUE){

                    //向下溢出

                    //throw newRuntimeException("向下溢出");

                    return 0;

                }

            }else{

                return 0;

            }

        }

                

       if(array[0]=='-'){

        //由于resultlong类型,返回值是int类型,因此在返回时需要强转为int 

                   return (int)(result*(-1));

       }else{

           return (int)result;

       }

    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值