题面

请实现一个函数用来判断字符串是否示意数值(包含整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"-1E-16"、"0123"都示意数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。

原题链接

剖析

除非承受过专业训练,否则一开始很难想到用自动机(Automata)来做,我是一开始凭直觉列举出不同的规定,而后一直的用测试用例试错,最终通过所有测试用例。

上面的代码没有任何参考意义,正文局部能够看一看。

做完本题最大的意义在于:

  1. 了解官网自动机解法的优越性
  2. 坚固了一些C++根底语法常识

源代码(正文局部即为思路)

class Solution {public:    bool isNumber(string s) {        char candidate[15] = {'0','1','2','3','4','5','6','7','8','9','.','+','-','E','e'};        set<char> cand;        for(int i=0; i<15; i++){            cand.insert(candidate[i]);        }        set<char> cand2;        for(int i=0; i<10; i++){            cand2.insert(candidate[i]);        }                //cand3没有存在的必要性        set<char> cand3;        for(int i=0; i<13; i++){            cand3.insert(candidate[i]);        }                int rawLen = s.length();        for(int i=0; i<rawLen; i++){                        if(s[i]==' '){                int tmpL = i;                int tmpR = i;                //避免空格有多个                while(s[tmpL]==' ' && tmpL>0){                    tmpL--;                }                while(s[tmpR]==' ' && tmpR<rawLen-1){                    tmpR++;                }                                if(cand.find(s[tmpL])!=cand.end() &&  cand.find(s[tmpR])!=cand.end()){                    return false;                }            }        }                //之前是判断和空格无关的状况        //删除掉所有的空格        s.erase(std::remove(s.begin(), s.end(), ' '), s.end());        //之后是去掉所有空格之后进行判断        int len = s.length();            //特判        if(len==0){            return false;        }        //特判        if(len==1){            if(s[0]=='+' || s[0]=='-' || s[0]=='.' || s[0]=='E' || s[0]=='e'){                return false;            }            else{                if(cand.find(s[0])!=cand.end()){                    return true;                }                else{                    return false;                }            }        }        //特判        if(s[1]=='+' || s[1]=='-' || s[len-1]=='e' || s[len-1] == 'E'){            return false;        }        /*后两个特判意义不大*/                                int dotNumber = 0;        int eNumber = 0;        int dotPosition = -1;        int ePosition = -1;        for(int i=0; i<len; i++){            if(cand.find(s[i])==cand.end()){                return false;            }            else{                if(s[i]=='.'){                    //.最多只能呈现一次                    dotNumber++;                    dotPosition = i;                    if(dotNumber>=2){                        return false;                    }                    if(dotPosition==len-1){                        if(cand2.find(s[dotPosition-1])==cand2.end()){                            return false;                        }                    }                    // cout<<dotPosition;                }                if(s[i] == 'e' || s[i]=='E'){                    eNumber++;                    ePosition = i;                    if(eNumber>=2){                        return false;                    }                }                if(s[i]=='+' || s[i]=='-'){                    if(ePosition==-1){                        if(i!=0){                            return false;                        }                    }                    else{                        if(i!=0){                            if(i!=ePosition+1){                                return false;                            }                        }                    }                }            }        }        //e之后不能再有小数点        if(ePosition !=-1 && dotPosition !=-1 && ePosition<dotPosition){            return false;        }                if(ePosition!=-1){            //e后面的那一个字符,必须是数字或者‘.'            if((ePosition-1)<0 || s[ePosition-1]=='+' || s[ePosition-1]=='-'){                return false;            }            else{                //如果e后面那一个字符是.                if(s[ePosition-1]=='.'){                    if((ePosition-2)<0 || cand2.find(s[ePosition-2])==cand2.end()){                        return false;                    }                }            }                        if(s[ePosition+1]=='+' || s[ePosition+1]=='-'){                if(ePosition+2>=len){                    return false;                }                for(int k=ePosition+2; k<len; k++){                    if(cand2.find(s[k])==cand2.end()){                        return false;                    }                }            }            //e前面第一位呈现的不是加号和减号            else{                if(ePosition+1>=len){                    return false;                }                for(int k=ePosition+1; k<len; k++){                    if(cand2.find(s[k])==cand2.end()){                        return false;                    }                }            }                    }        return true;    }};

提交后果:

官网题解

原文链接

C++语法常识坚固

  • set类型中,元素能够是char类型
  • char数组的赋值办法:

    char candidate[15] = {'0','1','2','3','4','5','6','7','8','9','.','+','-','E','e'};//留神,赋值号左边是大括号char candidate[6] = "Hello";//留神,字符串前面自带一个\0,所以char数组的长度要比字符串视觉长度大1

    试验演示:

    #include <iostream>#include <string.h>using namespace std;int main(){    char candidate[6] = "Hello";    cout<<candidate<<endl;    cout<<sizeof(candidate)<<endl;    //strlen函数蕴含在string.h头文件里    //string.h头文件蕴含C语言中的字符串处理函数,如strlen,strcmp等等    //string头文件蕴含C++中的STL模板string    cout<<strlen(candidate)<<endl;    return 0;}

  • 判断某个元素是否在set类型中:

    set<typename> now;if(now.find(element)==now.end()){    //element元素不在now汇合中    cout<<"element元素不在now汇合中";}