java表示数值的字符串通俗详解

表示数值的字符串

http://www.nowcoder.com/questionTerminal/6f8c901d091949a5837e24bb82a731f2

根据题意,我们首先要考虑的是字符串是数值的基本模式,即(整数部分A).(小数部分B)(指数部分C),例如(+1).(23)(e-2),(3).(23)(e1),
其分别表示为1.23e-2/3.23e1.
接着我们需要考虑整数部分/小数部分/指数部分分别可以有哪些表现形式,即哪些是合法的。
1.对于整数部分来说,它可以是不带符号的整数(1,2,3,4.....),也可以是带正负号的整数(-1,+1,-2,+2......),但是正负号需在整个整数部分的最前面,不能出现在其他位置.因此满足整数部分位置合法的条件是整数部分是无符号整数或有符号整数;

2.再来看小数部分,由于小数部分处于小数点之后的位置,因此这部分数字中不能带有符号.因此小数部分的合法条件是小数部分是无符号整数;

3.最后再来看指数部分,由于指数,即e肩膀上的数可正可负,因此指数部分的合法条件是有符号整数或无符号整数,我们可以注意到这部分的合法条件与整数部分相同.

再确定了基本模式,以及各部分的合法条件后我们需要解决如何表示这些合法条件的问题.即如何判断其是合法符号整数或合法无符号整数.这部分的判断可以单独设立两个函数,方法很简单,如下:
 private boolean UnsignedInt(char[] str){
        int c=index;
        while(index<str.length&&(str[index]>='0'&&str[index]<='9'))
           index++;
        return index>c;
    }
           
    private boolean SignedInt(char[] str){
        if(index<str.length&&(str[index]=='+'||str[index]=='-'))
           index++;
        return UnsignedInt(str);
    }
这部分代码很容易理解,但要注意边界条件,否则很容易出现数组越界的问题.这里当判断到最后一位,即str.length-1时如果依然满足条件,则index++,然后退出即可,数组不会越界;我们可以看到SignedInt方法是用来判断整数部分A和指数部分C的合法性方法;通过在无符号整数前加入判断'+'/'-'即可满足;
再完成了合法性判断条件后,我们来使用一个全局变量index进行数组的遍历;
首先我们需要注意特指的判断,这里不多解释:
 if(str==null||str.length<1) return false;
在正式开始前,我们需要判断在整数部分前是否存在空格,如果存在跳过空格;同样对于结尾,如果存在空格,跳过空格:
while(index<str.length&&str[index]==' ')
            index++;
随后进入第一部分,整数部分A的判断,调用SignedInt方法即可,此时index指针指向整数部分后的第一个位置.可能会出现多种情况:
1.如果index指向'.',那么直接index++,判断后续的部分,即小数部分B是否为无符号整数,调用UnsignedInt即可.判断完毕后,我们需要确定连接性.我们知道例如123./.123/123.123均是合法表示,因此只要小数点前后有一部分合法性为true,那么到小数部分为止,字符数组合法.(如果后续出现e,后续判为假即可)
2.如果index指向'e',那么直接index++,判断后续部分,即指数部分是否为符号/无符号整数,调用SignedInt即可.判断完毕后,我们需要确定连接性,我们知道.e1/12e/12e-1.2均为非法表示,因此在e的前面必须有数字,且e的后面必须是(有符号或无符号)整数.
3.如果均不是,那么说明数组已经遍历完成或还有几个空格,吸收空格后可以做最终判断:
return numberic&&index==str.length;//numberic是一个表示数组合法性的boolean变量
注意由于无法确定index是否越界,所以每次再判断前都需要判断index是否小于数组长度,否则会造成数组越界.
如果我们使用一个可以扩容的ArrayList或String来存储字符串,那么可以通过在末尾加入结束符的方式,来减少越界判断.
//添加结束标志
        s = s + '|';

本题整体代码如下:
public class Solution {
    int index=0;
    public boolean isNumeric(char[] str) {
        if(str==null||str.length<1)
            return false;
        while(index<str.length&&str[index]==' ')
            index++;
        boolean numberic=SignedInt(str);
        if(index<str.length&&str[index]=='.'){
            index++;
            //注意这里的并列顺序,需要将UnsignedInt函数放在numberic之前,否则如果numberic为true后面UnsignedInt将不执行
            numberic=UnsignedInt(str)||numberic;  
        }
        
        if(index<str.length&&(str[index]=='e'||str[index]=='E')){
            index++;
            numberic=SignedInt(str)&&numberic;
         }
        while(index<str.length&&str[index]==' ')
            index++;
        return numberic&&index==str.length;
    }        
    
    //realize the UnsignedInt
    private boolean UnsignedInt(char[] str){
        int c=index;
        while(index<str.length&&(str[index]>='0'&&str[index]<='9'))
           index++;
        return index>c;
    }
           
    private boolean SignedInt(char[] str){
        if(index<str.length&&(str[index]=='+'||str[index]=='-'))
           index++;
        return UnsignedInt(str);
    }
}







全部评论
我一开始ac失败,发现是UnsignedInt(str)||numberic;这里位置的问题,切记不能互换
点赞 回复 分享
发布于 2020-11-11 13:12

相关推荐

11-26 22:34
已编辑
重庆邮电大学 Java
快手 客户端开发 (n+5)k*16 公积金12
点赞 评论 收藏
分享
10-17 10:05
已编辑
北华大学 全栈开发
牛客872465272号:掉头发了哥
点赞 评论 收藏
分享
蚂蚁 基架java (n+6)*16 签字费若干
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务