第六十四题 模拟第四题
是上一题的复杂版本,要判断很多东西,极其复杂
小数点前后 是否符合要求
e前后是否符合要求
空格是否符合要求
符号是否符合要求

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param str string字符串 
     * @return bool布尔型
     */
    bool isNumeric(string str) {
        // write code here
        int n = str.length();
        int index = 0;
        
        // 去除前空格
        while(index < n) {
            if (str[index] != ' ')
                break;
            index++;
        }
        // 如果说只有空格 直接return false
        if(index == n) 
            return false;
        
        // 第一个非空字符决定了符号(可能有 也可能没有)
        int sign = 1;
        if(str[index] == '+')
            index++;
        else if(str[index] == '-') {
            index++;
        }
        // 如果说只有一位,并且不是数字,直接返回false
        if(index==n && ( str[index]< '0' || str[index] > '9' ))
            return false;
        
        // 用来记录小数点和e是否出现过,因为都只能出现1次
        int point=0;
        int e=0;
        while(index < n){
            // c记录了当前的字符
            char c = str[index];
            index++;
            // 如果是数字 则直接向后遍历
            if(c >= '0' && c <= '9')
                continue;
            
            // 如果说是e
            // 要判断:
            // 是否出现过e了,如果出现过直接return false,然后修改e为出现过,并且e后面必须要求是整数了,所以小数点修改为1
            // 接下来要判断e前后是否符合要求
            // e前只能是数字 或者 小数点
            // e后是否是整数(可能有符号,有符号 就先往后遍历一个 删除符号)
            // 然后删除符号后,判断后面是否是数字,是的话 继续向后遍历,不是的话 直接return false
            else if(c=='e' || c=='E')
            {
                if(e==1)
                    return false;
                e=1;
                point=1;
                
                if( index-2<0 ||( str[index-2]< '0' || str[index-2] > '9' ) && str[index-2] !='.')
                    return false;
                if(str[index] == '+')
                    index++;
                else if(str[index] == '-') {
                    index++;
                }
                
                // 如果说.后面有数字则对
                if( index !=n && ( str[index]>='0' || str[index] <= '9' ) )
                    continue;
                else
                    return false;
            }
            
            // 如果是小数点
            // 小数点只能出现一次,并且不能出现在e后面,所以先判断是否可以出现小数点
            // 接下来继续判断小数点的位置是否符合要求:
            // 首先小数点后面如果说跟着的是数字或者e,那么肯定对
            // 如果说 小数点后面不是数字或者e,就要判断小数点前一位是否是数字,如果前一位也不是数字,直接return false
            else if(c=='.')
            {
                if(point==1)
                    return false;
                point=1;
                // 如果说.后面有数字或者e则对
                if( index < n && ( str[index]>='0' && str[index] <= '9' ) || str[index]=='e')
                    continue;
                
                // 如果后面不是数字,则要看前面是否是数字
                if(index-2<0 || ( str[index-2]< '0' || str[index-2] > '9' ) )
                    return false;
            }
            
            // 如果是空格,则后面所有的都必须是空格
            else if(c==' ')
            {
                // 去除后面所有的空格,如果不是空格,看看是否结束了
                // 如果没结束就代表空格之后有字符 return false
                // 如果结束了,就代表遍历完成,return true即可
                while(index < n) {
                    if (str[index] != ' ')
                        break;
                    index++;
                }
                if(index == n)
                    return true;
                else
                    return false;
            }
            
            // 如果说 不是 '空格''、'.'、'e'直接返回false
            else
                return false;
        }
        
        
        return true;
    }
};