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

      

  • 相关阅读:
    LVS+Heartbeat 高可用集群方案操作记录
    Haproxy和Nginx负载均衡测试效果对比记录
    Haproxy+Keepalived高可用环境部署梳理(主主和主从模式)
    Haproxy 重定向跳转设置
    Haproxy+Heartbeat 高可用集群方案操作记录
    haproxy反向代理环境部署(http和https代理)
    Linux下对lvm逻辑卷分区大小的调整(针对xfs和ext4不同文件系统)
    LVM基础详细说明及动态扩容lvm逻辑卷的操作记录
    Apache运维中常用功能配置笔记梳理
    LVS负载均衡-基础知识梳理
  • 原文地址:https://www.cnblogs.com/dreamrun/p/4535774.html
Copyright © 2011-2022 走看看