zoukankan      html  css  js  c++  java
  • No.65 Valid Number

    No.65 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.

    分析:典型的细节实现题

         这个题本身并不难,就和atoi( )函数一样,其实考察的是各种情况考虑是否周全。以下为一些注意事项:

    1. 前后空白的处理
    2. 记录第一个非空白且非正负号的位置,这样实现时更方便
    3.  就算是用指数表示法,其指数部分必须为整数,所以小数点只可能有一个,且其前后必须有数字
    4. 越界问题,常常被忽略,各种情况下的越界
    5. 边界问题:e或.是否在首(非空白、非正负号)尾位置  
    6. 真是细节决定成败啊,每次提交,总有遗漏的情况,而且,测试用例自己写的时候,偏重于非法的,以至于合法的情况过少,反而考虑不周,导致出错

     

      1 #include "stdafx.h"
      2 #include <string>
      3 #include <iostream>
      4 //include <ctype.h>//isalnum(),isalpha,isdight()
      5 using namespace std;
      6 
      7 inline bool isNum(int x)
      8 {
      9     if(x>='0' && x<='9')
     10         return true;
     11     return false;
     12 }
     13 class Solution
     14 {
     15 public:
     16     bool isNumber(string s)
     17     {/*
     18         判断输入的字符串是否是数字[难就难在要考虑各种情况]
     19         整数、小数、负数、浮点数表示
     20         浮点数表示法:小数表示法[整数和小数部分不能同时省略];
     21                       指数表示法[指数部分以e或E开始,且必须为整数;e或E两边至少有一位数]
     22         有效字符:0~9、+、-、首尾空白、e、E、.、                
     23         忽略头尾空白
     24         
     25         复数就不考虑了吧。。。3+2i
     26         注意:e9不合法!!!
     27         特例:
     28             false:"+"、"-"、"."
     29     */
     30         if(s.size() == 0)
     31             return false;
     32 
     33         auto it = s.begin();
     34         while(it != s.end() && (*it) == ' ')//忽略前面的空格,指向第一个非空格位置
     35             it++;
     36 
     37         auto iend = s.end()-1;//用于标识最后一个非空格位置后的第一个空格处,即尾后
     38         while(iend >= it && (*iend) == ' ')
     39         {
     40             iend--;
     41         }
     42         iend++;//iend标识的是。 
     43         if(it == iend)
     44             return false;//只有空格!!!之前漏了
     45 
     46         if(it != iend)//开头为正负号
     47         {
     48             if((*it) == '+' || (*it) == '-' )
     49                 it++;
     50             if(it == iend)//仅有正负号,不是数字
     51                 return false;
     52         }
     53         auto ibegin = it;//用于标识第一个非空位置 且不是正负号的位置!!!
     54 
     55         bool isFloat = false;//标识是否为指数表示法,即有没有e或E
     56         bool isPoint = false;//小数点是否出现
     57         //之后,有效字符为./e/E/0~9/+/-(正负号仅允许在e或E之后)
     58         while(it != iend)
     59         {
     60             if(isNum(*it))//是数字,直接判断下一位
     61             {
     62                 it++;
     63                 continue;
     64             }
     65             if((*it) == '.')//是小数点
     66             {//只可能有一个小数点,因为指数部分必须为整数!!!之前忘了
     67                 if(isPoint || isFloat)//!!!之前遗漏了
     68                     return false;//e或E出现了也不可以再出现小数点!!!
     69                 if(it == ibegin)
     70                 {
     71                     if(it+1 == iend)//注意越界判断!!!
     72                         return false;
     73                     if(it < iend && !isNum(*(it+1)))//小数点前后必须得有数字!!!.e2
     74                         return false;
     75                 }
     76                 isPoint = true;
     77                 it++;
     78 /*
     79                 if(it == iend)//这一步没必要了,因为上一个if已经判断了!!!
     80                 {
     81                     if((it-1) != ibegin && isNum(*(it-2)))
     82                     //!!!前面有且有数字才可以,两个条件之前都漏了;而且,是-2,不是-1;(it-1)而不是it
     83                         return true;
     84                     else
     85                         return false;//只有.,不是数字
     86                 }
     87 */
     88                 continue;        
     89             }
     90             if((*it) == 'e' || (*it) == 'E')
     91             {
     92                 if(isFloat || it == ibegin)
     93                 //||!isNum(*(it-1)))//e或E已经出现过!!!之前漏了;ibegin改为包括正负号,就不需要这个条件了
     94                 //e2不合法哟,所以也要加上是否为第一个非空白字符!!!
     95                 //若不是第一个非空字符,前一个还必须得是数字,+E2不合法;
     96                 //得-1呀,亲
     97                     return false;
     98                 else
     99                     isFloat = true;
    100                 it++;
    101                 if(it == iend) //要保留,因为后面判断正负号可能存在越界
    102                     return false;//e后面必须跟数字,所以,与小数点情况是不同的,之前弄错了!!
    103                 //只有在e后面紧跟着的正负号,且只有一个正负号,才是有效的
    104                 if((*it) == '+' || (*it) == '-')
    105                     it++;
    106                 if(it == iend)
    107                         return false;//2.3e+,2.3E-不是数字
    108 
    109                 continue;
    110             }
    111             if(1)//如果到达这里,说明不是有效字符
    112                 return false;
    113         }        
    114         return true;
    115     }
    116 };
    117 
    118 
    119 int main()
    120 {
    121     Solution sol;
    122 //    cout<< sol.isNumber(" 46.e3 ")<<endl;
    123     string test[] = {string("0"),string(" 0.1 "),string("2e10"),string("-3.4e-2"),string("112345"),
    124                      string("1.044"),string(" 1.044 "),string("1e2"),string("1."),
    125                      string(".2"),string("+1."),string(" -1."),string("005047e+6"),
    126                      string("2e0"),string("46.e3"),
    127                      string("e2"),//不合法哟
    128                      string("1.a"),string(" "),string("."),string("1.."),string("6e6.5"),
    129                      string("abc"),string("1 a") ,string("+"),string("-"),string(" . "),
    130                      string("2.3.4"),string("e "),string("2.3e+"),string("2.3e-"),string(""),
    131                      string("ee"),string("+."),string("+e"),string("++e2"),string("1e")
    132                     };
    133 
    134     
    135     //true;
    136     //false
    137     //还是漏了几种情况:string("1.")、string("1e"),string("+1."),string(" -1."),string("e22e2"),string("-3.2e3.4")
    138     //提交错误用例:e2,.e1,+E3,2e0(应该正确),46.e3(应该正确)
    139 
    140     std::cout << boolalpha ;
    141     for(auto const &i : test)
    142         cout<< i << " : " << sol.isNumber(i)<<endl;
    143 
    144     return 0;
    145 }

    参考:https://github.com/haoel/leetcode/blob/master/algorithms/validNumber/validNumber.cpp

      

  • 相关阅读:
    LeetCode Binary Tree Inorder Traversal
    LeetCode Populating Next Right Pointers in Each Node
    LeetCode Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode Reverse Linked List II
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Pascal's Triangle
    Palindrome Construct Binary Tree from Preorder and Inorder Traversal
    Pascal's Triangle II
    LeetCode Word Ladder
    LeetCode Binary Tree Zigzag Level Order Traversal
  • 原文地址:https://www.cnblogs.com/dreamrun/p/4535774.html
Copyright © 2011-2022 走看看