表示数值的字符串:最直观的想法是,判断是否可以将字符串str转换为浮点数float,此处可以调用python中的内置函数float,如果发现异常则返回false,否则返回true。注意,虽然C++中的stof函数也能够把字符串转换成浮点数,但是其是读取到不满足即停止,比如字符串"1.2.3",stof会将其转换为1.2,但实际上整体是不能转换的。注意,python代码注意缩进。

def isNumeric(self , str: str) -> bool:
    try:
        float(str)
    except:
        return False
    return True

正则匹配:其实,该题描述,数字、空格、字母、正负号等,非常适合正则匹配,但是使用正则匹配需要对正则比较熟练。

  • ^:匹配行开头;
  • $:匹配行结尾;
  • . :除换行的任意字符;
  • []:匹配[]中的任意一个字符;
  • ():设定分组,有几个()就有几个相应的匹配字符串;
  • \d:数字;
  • \D:\d取反;
  • \w:字母数字下划线;
  • \W:\w取反;
  • \s:空格;
  • \S:\s取反;
  • *:前面元素重复0次或者多次;
  • +:前面元素重复1次或者多次;
  • ?:前面元素重复0次或者1次;
  • \\:\;
  • |:逻辑或;
  • {n}:前面元素重复n次;
  • {n,}:前面元素重复至少n次;
  • {n,m}:前面元素重复至少n次,至多m次;

#include<regex> //导入库
regex pattern("……");  //模式串
smatch result; //匹配结果
bool ret=regex_match(str,result,pattern); //正则匹配
bool isNumeric(string str) 
{
    //\\s*表示若干空格
    //[+-]?表示正负号可选
    //(\\d+|\\d+\\.\\d*|\\.\\d+)表示整数或小数部分
    //([eE][+-]?\\d+)表示整数部分
    //\\s*表示若干空格
    regex pattern("\\s*[+-]?(\\d+|\\d+\\.\\d*|\\.\\d+)([eE][+-]?\\d+)?\\s*");
    return regex_match(str,pattern);
}

常规判断:符合大多数人直觉的解法还是枚举法,枚举各种情况,遍历每一个字符,然后根据各种可能的情况进行标记。使用布尔变量isNum标记之前是否出现过数字,使用布尔变量isDot标记之前是否出现过小数点,使用布尔变量isE标记之前是否出现过e或者E,三个变量均初始化为False。如果当前字符为数字则标记遇到数字;如果当前字符为小数点则需要判断小数点之前不能出现小数点或者e或者E;如果当前字符为e或者E则需要判断其前面必须要出现过数字并且不能出现e或者E同时后面可以出现数字;如果当前字符为正负号则其必须是第一个非空白位置或者是e或者E后面的第一个位置。如果上述满足,那么根据isNum是真还是假来返回。

remove(beg,end,value);  //移除区间(beg,end)中每一个“与value相等”的元素;
str.erase(remove(str.begin(),str.end(),' '),str.end()); //删除字符串str两边的空格;

bool isNumeric(string str) 
{
    bool isNum=false,isDot=false,isE=false;
    //删除字符串str两边的空格
    str.erase(remove(str.begin(),str.end(),' '),str.end());
    //cout<<str<<endl;
    //cout<<str.size()<<endl;
    for(int i=0;i<str.size();i++)
    {
        if(str[i]>='0'&&str[i]<='9') //标记数字
            isNum=true;
        else if(str[i]=='.') //遇到小数点
        {
            if(isDot||isE) //判断合法性
               return false;
            isDot=true; //标记小数点
        }
        else if(str[i]=='e'||str[i]=='E') //遇到e/E
        {
            if(!isNum||isE) //判断合法性
               return false;
            isE=true; //标记e/E
            isNum=false; //后面可以出现数字
         }
         else if(str[i]=='+'||str[i]=='-')
         {
            if(i!=0&&str[i-1]!='e'&&str[i-1]!='E')
              return false;
         }
         else //不合法字符
         {  
            return false;
         }
    }
    return isNum;
}