65. Valid Number-Leetcode

处理字符串类型判断的常见问题

首位空格的处理

//相比较只对字符串的小标进行移动来处理非空序列,这种直接删除的方式后期判断能更快,而且省掉了记录字符首尾下标的麻烦
while(s[0]==' ')
            s.erase(0,1);
  while(s[s.length()-1]==' ')
            s.erase(s.length()-1,1);

关于数字的判断规则

此处是最大的难点,跟普通的认为是否为数字的规则不同,一些形如".1""1.""1.e1"的方式均为数字,应该返回true。例如:

特例:" ":s.length()==0
    "3":忘了对sign进行初始化
    ".1":是true,
    "3.":是数字
    ".e1"应该返回false
    "-."false
    "+.8"应该是true

所以普通的遍历完之后再进行单纯统计的方式不够直接
看了discuss区的讨论之后得出一个大致的方法来判断是否是数字。

解法

1.按照规则遍历

见到的解法:

一个有效的数字由有效数和指数组成(这是可选的),遍历:
跳过领先的空格;
检查有效数字是否有效。要做到这一点,只需跳过前面的标志(正负符号位),并计算位数和点数。有效的有效数字不超过一个点,至少有一个数字。
检查指数部分是否有效。如果有效数字后面跟着'e',我们这样做。只需跳过前面的标志并计算位数。一个有效的指数至少包含一个数字。
跳过尾随的空格。如果字符串是一个有效的数字,我们必须达到0。

对应的解法如下:

class Solution {
public:
    bool isNumber(string s) {
         int i = 0;
    
    // skip the whilespaces
    for(; s[i] == ' '; i++) {}
    
    // check the significand
    if(s[i] == '+' || s[i] == '-') i++; // skip the sign if exist
    
    int n_nm, n_pt;
    for(n_nm=0, n_pt=0; (s[i]<='9' && s[i]>='0') || s[i]=='.'; i++)
        s[i] == '.' ? n_pt++:n_nm++;       
    if(n_pt>1 || n_nm<1) // no more than one point, at least one digit
        return false;
    
    // check the exponent if exist
    if(s[i] == 'e') {
        i++;
        if(s[i] == '+' || s[i] == '-') i++; // skip the sign
        
        int n_nm = 0;
        for(; s[i]>='0' && s[i]<='9'; i++, n_nm++) {}
        if(n_nm<1)
            return false;
    }
    
    // skip the trailing whitespaces
    for(; s[i] == ' '; i++) {}
    
    return i==s.length();  // 或者s[i]==0
    }
};

2.自动机

discuss区还提供了一种自动机的解法,但是对我来说可行性不高,贴出来
http://blog.csdn.net/kenden23/article/details/18696083

    原文作者:analanxingde
    原文地址: https://www.jianshu.com/p/b20971a95180
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞