题面
请实现一个函数用来判断字符串是否示意数值(包含整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"-1E-16"、"0123"都示意数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。
原题链接
剖析
除非承受过专业训练,否则一开始很难想到用自动机(Automata)来做,我是一开始凭直觉列举出不同的规定,而后一直的用测试用例试错,最终通过所有测试用例。
上面的代码没有任何参考意义,正文局部能够看一看。
做完本题最大的意义在于:
- 了解官网自动机解法的优越性
- 坚固了一些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汇合中";}