[Leetcode]Valid Number


Validate if a given string is numeric.
Some examples:
"0" =>  true
" 0.1 " =>  true
"abc" =>  false
"1 a" =>  false
"2e10" =>  true
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

This is really a trivial question, a lot of corner cases need to be found, just like the Stirng to Integer question.


首先要明确所有可能的计数法,对于一般科学计数法和普通的计数法,能够出现的字符无非是'+', '-', '0-9', '.', 'e'

有几点很重要:

1. 数中间不能有空格

2. 正负号可以出现在数得最前端也可以出现在e之后的最前端,两部分中正负号都只能出现一次. 正负号不影响后续符号的行为

3.小数点只能出现一次,并且不能出现在e后面,并且必须要有数字存在,不能单独一个小数点。小数点出现后会影响到后续正负号,小数点后不能再出现正负号了

4. e一开始不能出现,必须在前面有数字(小数点和正负号不行)的情况下才能出现。e出现了一次以后就不能再出现了。e出现之后,会开放后续放置小数点和正负号的权限,但是由于e前后都需要数字,e出现后的hasNum标记要变为false,因为相当于后半部分又没有数字了。

5. 数字一开始标记为无,出现数字后,其会影响e的放置权限,如果出现数字并且没有e存在的情况下,那么e的放置权限开放。放入数字后就不能再出现正负号。

6. 其他一切字符出现都是false。


几种很难考虑的corner case

'.': false 

'+.8e1': true

'+.8e1.1': false

'e': false


public boolean isNumber(String s) {
		if (s==null ){
            return false;
        } 
        // trim off head and tail zeros which not affect result depend on question
        s=s.trim();
        if(s.length()==0){
            return false;
        } 
       boolean hasNum=false;
       
       boolean canSign=true;
      
       boolean canDot=true;
      
       boolean canE=false;//At first we cannot put e until there is a number or other things
       boolean hasE=false;
       
       int i=0;
       while(i<s.length()){
           char c=s.charAt(i++);
           
           if (c==' '){
             //中间可能有空格
              return false;
               
           }
           
           if (c=='+' ||c=='-'){
               //当正负号第一次进入的时候,并且在e之前,正负号只对自身有影响,出现了以后在e出现之前就不能再出现了
               if (!canSign){
                   return false;
               }
               canSign=false;
               
               continue;
           }
           
           if (c=='.'){
               if (!canDot){
                   return false;
               }
               canDot=false;//有点之后就不能再有小数点了
               canSign=false;//有点之后在e出现之前都不能再有正负号了
               continue;
           }
           
           if (c=='e'){
               
               if (!canE||hasE){//When e comes, we already have e or we cannot put e, we return false
                   return false;
               }
               
               canE=false;//e出现之后,我们就不能再放置e了,换言之e只允许出现一次
               hasE=true;//顾名思义变成true
               hasNum=false;//出现e之后,之前有的是否有数字的信息清零,hasNum变false
               canDot=false;//出现e之后,再也不能出现点了,所以canDot变为false
               canSign=true;//出现e之后,之前是否有正负号信息清零,canSign变成true,e之后可以出现正负号
               
               continue;
           }
           
           
           if (c>='0' && c<='9'){
               hasNum=true;//有数字读入
               //只有当有数字读入之后我们才能考虑开放e的放置权限
               if (!hasE){//当放入一个数之后,如果我们处于不能放e并且现在也没有e的状态,则意味着下一个可能会放入的e将会是第一个e,所以设置canE = true表示可以放入下一个可能的e
                   canE=true;
               }
               
               canSign=false;//放入数字后就不能再放入符号了
             
               
               
           }
           else{
               return false;
           }
           
           
       }
       
       return hasNum;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值