• 小练习:vaild number


    1.描述

      给定字符串,若该字符串表示的是数字,则输出true,否则输出false

    2.分析

      题目一看感觉不难,做起来却很麻烦,首先是数字的各种表示要知道,然后就是对这些不同形式的数字进行筛选判断。该题目中合法数字的表示形式如下:

    ±12  // 前缀有正负号合法
    1.2   
    1.    
    .1    
    1e2
    1.e2 
    1e±2
    
    //以上数字中间不含空格    

      思路:

      总原则,出现非法字符(.e±1234567890及空格之外的)直接false,'.''e'出现两次以上的直接false,有效字段中包含空格的直接false,以'e'开头和以'e''+''-'结尾的直接false

      01.首先是缩减字符到有效字段,即一头一尾各一个哨兵,然后相向排除(空格),全都到达合法字符处后结束缩减,例如:

    "   12 ee 23 " -> "12 ee 23" // 对于有效字段内部不检查
    "  e12 " -> false
    " 123+   " ->false

      02.由上步骤确定的两个首位哨兵位置,对有效字段内部进行排查

      03.在有效字段内逐个检查,出现非法字符或者出现空格的直接false,否则对出现的有效字符进行分类检查

    3.代码

    bool isNumber(string s){
    const char* sp = s.c_str();
    
    int eFlag = 0, dotFlag = 0, startFlag = 0, spaceFlag = 0, numFlag = 0, dotEFlag = 0, signFlag = 0, esignFlag = 0, signnumFlag = 0; //一些标志位
    int i = 0, j = s.length() - 1; // 设立哨兵
    
    for (;;) // 压缩头尾,提取有效字段
    {
        if (sp[i]<48 || sp[i]>57)
        {
            if (sp[i] != '+'&&sp[i] != '-'&&sp[i] != '.'&& sp[i] != ' ' && sp[i] != 'e' || i>j) //非法字符检查
                return false;
        }
    //-----------------------------------------------------+
        if (sp[i] == 'e') // 头--->
            return false;
        else
        {
            if (sp[i] == ' ' || sp[i] == '+' || sp[i] == '-')
            {
                if (signFlag)
                    return false;
    
                if (sp[i] == '+' || sp[i] == '-')
                    signFlag = 1;
                i++;
            }
            else
                startFlag = 1;
    
    
        }
    //-----------------------------------------------------+
        if (sp[j] == 'e' || sp[j] == '+' || sp[j] == '-')  // <---尾
            return false;
        else
        {
            if (sp[j] == ' ')
                j--;
            else if (startFlag)
                break;
        }
    
    }
    //-----------------------------------------------------+
    for (; i<j + 1; i++)  //对有效字段内进行检查
    {
        if (sp[i]<48 || sp[i]>57) 
        {
            if (sp[i] != '.'&& sp[i] && sp[i] != 'e'&&sp[i] != '+'&&sp[i] != '-') // 排除非法字符
                return false;
        }
        else
        {
            numFlag = 1;
        }
    //-----------------------------------------------------+
        if (sp[i] == 'e') // 为'e'的情况
        {
            eFlag++;
    
            esignFlag = i; //用来检查 "1e±1"类型
            if (i == 1 && dotEFlag) //用来排除".e1"类型
                return false;
            if (i == (j - 1))
                dotEFlag = 1;
    
            if (eFlag>1)
                return false;
        }
    //-----------------------------------------------------+
        else if (sp[i] == '.') // 为 '.' 的情况 非法情况是 ".e1""..1"等
        {
            dotFlag++;
            if (i == 0)
                dotEFlag = 1;
    
            if (dotEFlag&&i == j) // 用来检查e在.前
                return false;
    
            if (eFlag)
                return false;
    
            if (dotFlag>1)
                return false;
    
        }
    //-----------------------------------------------------+
        else if (sp[i] == '+' || sp[i] == '-') //为'+''-'的情况
        {
            signnumFlag++;
            if (i>esignFlag + 1||!eFlag)
                return false;
            if (signnumFlag>1)
                return false;
        }
    
    }
    if (!numFlag)
        return false;
    return true;
    }

      经过测试,算法可以使用。

    ------------ 转载请注明出处 ------------
  • 相关阅读:
    OpenCVPython系列之模板匹配
    OpenCVPython系列之轮廓的高级功能
    视频处理入门
    OpenCVPython系列之拉普拉斯算子
    OpenCVPython系列之顶帽与黑帽操作
    OpenCVPython系列之图像的几何变换
    OpenCVPython系列之图像缩放旋转平移
    OpenCV中的绘图功能
    OpenCVPython系列之OTSU算法
    OpenCVPython系列之轮廓特征初阶
  • 原文地址:https://www.cnblogs.com/whlook/p/6493247.html
Copyright © 2020-2023  润新知