文章目录

  • 题目
  • 思路一
  • 代码一
  • 思路二
  • 代码二

题目



思路一

考察有限状态自动机(参考jyd):

字符类型:

空格 「 」、数字「 0—9 」 、正负号 「 ± 」 、小数点 「 . 」 、幂符号 「 eE 」 。

状态定义:

按照字符串从左到右的顺序,定义以下 9 种状态:

  1. 开始的空格
  2. 幂符号前的正负号
  3. 小数点前的数字
  4. 小数点、小数点后的数字
  5. 当小数点前为空格时,小数点、小数点后的数字
  6. 幂符号
  7. 幂符号后的正负号
  8. 幂符号后的数字
  9. 结尾的空格

结束状态:

合法的结束状态有 2, 3, 7, 8 。

算法流程:

  1. 初始化:

    1. 状态转移表 maps : 设 maps[i] ,其中 i 为所处状态(9种之一), maps[i] 使用哈希表存储可转移至的状态。键值对 (key, value) 含义:若此时的字符是 key ,则可从状态 i 转移至状态 value 。
    2. 当前状态 p : 起始状态初始化为 p = 0 。
  2. 状态转移循环: 遍历字符串 s 的每个字符 c 。

    1. 记录字符类型 t : 分为四种情况。

      • 当 c 为正负号时,执行 t = 's' ;
      • 当 c 为数字时,执行 t = 'd' ;
      • 当 c 为 e , E 时,执行 t = 'e' ;
      • 当 c 为 . , 空格 时,执行 t = c (即用字符本身表示字符类型);
      • 否则,执行 t = ‘?’ ,代表为不属于判断范围的非法字符,后续直接返回 false。
    2. 终止条件: 若字符类型 t 不在哈希表 maps[p] 中,说明无法转移至下一状态,因此直接返回 False 。

    3. 状态转移: 状态 p 转移至 maps[p][t]

  3. 返回值: 跳出循环后,若状态 p∈2,3,7,8 ,说明结尾合法,返回 True ,否则返回 False 。

再详细说一下状态转移表的作用(下面代码部分的注释中有结合实例进行详解):

  • 处于第 i 行表明此时遍历到的字符是第 i+1 种状态(可以对照上文的状态定义)
  • 那么我下一个字符可以是第 i 行中的各个 key 对应的字符。
  • 如果某字符没有写进第 i 行,表示 i+1 状态的下一个字符不应是某字符

复杂度分析:

  1. 时间复杂度 O(N) : 其中 N 为字符串 s 的长度,判断需遍历字符串,每轮状态转移的使用 O(1) 时间。
  2. 空间复杂度 O(1) : maps 和 p 使用常数大小的额外空间。

代码一

class Solution {public:bool isNumber(string s) {vector<map<char,int>> maps = {// 状态转移表
// 以第一行为例,状态转移表的含义为:
// 开始的空格其下一个字符可以继续是空格,也可以是符号、数字、小数点,
// 但不可是第0行不存在的e。
// 也就是为了保证字符串是数值,空格后面不能直接跟一个幂符号。{{' ', 0},  {'s', 1},  {'d', 2},  {'.', 4}}, // 开始的空格{{'d', 2}, {'.', 4}}, // 幂符号前的正负号{{'d', 2}, {'.', 3}, {'e', 5}, {' ', 8}}, // 小数点前的数字{{'d', 3}, {'e', 5}, {' ', 8}}, // 小数点、小数点后的数字{{'d', 3}}, // 当小数点前为空格时,小数点、小数点后的数字{{'s', 6}, {'d', 7}}, // 幂符号{{'d', 7}}, // 幂符号后的正负号{{'d', 7}, {' ', 8}}, // 幂符号后的数字{{' ', 8}} // 结尾的空格};int p = 0; //起始状态char t;for(char c : s) {if(c >= '0' && c <= '9') t = 'd';else if(c == '+' || c == '-') t = 's';else if(c == 'e' || c == 'E') t = 'e';else if(c == '.' || c == ' ') t = c;else t = '?';if(maps[p].find(t) == maps[p].end()) return false;p = maps[p][t];}return p == 2 || p == 3 || p == 7 || p == 8;}
};

思路二

用 bool 类型变量 ret 存储搜索过程中的结果,整个搜索过程如下:

  1. 过滤首部空格
  2. 过滤正负号,紧接着检查是否有数字
  3. 遇到第一个不是数字的字符,应为 '.' 或者 e
  4. '.' 的后面可以有 e,但 e 的后面不能有 '.' ,所以先处理 '.' 再处理 e
  5. '.' 前面可以什么都没有,后面也可以什么都没有,只要有一边有数据就行
  6. e 的前后必须都要有数据,并且后面可以存在正负号,所以需要过滤正负号
  7. 过滤尾部空格
  8. 检查 ret 状态以及是否已经遍历完字符串

关于第8点检查是否已经遍历完字符串:

因为如果字符串是数值,尾部空格应该是字符串的末尾部分倒数几个字符,空格完了字符串应该也就结束了。如果过滤完了尾部空格还有字符,说明该字符串不是数值。

代码二

class Solution {public:bool scanDigit(string s, int& i){int count = i;while(i != s.size()){if(isdigit(s[i]))++i;elsebreak;}return i > count;//如果数据中没有一个数字,则直接返回false,有则返回true}bool scanSign(string s, int& i){if(i < s.size() && s[i] == '+' || s[i] == '-'){++i;}//过滤正负号return scanDigit(s, i);}bool isNumber(string s) {if(s.empty())return false;int i = 0;while(s[i] == ' ')++i;//过滤首部空格bool ret = scanSign(s, i);//第一遍搜索,先走完.或者e前的所有数字//.的后面可以有e,但e的后面不能有.,所以先处理.再处理eif(i < s.size() && s[i] == '.'){ret = scanDigit(s, ++i) || ret;//.前面可以什么都没有,后面也可以什么都没有,只要有一边有数据就行}if(i < s.size() && (s[i] == 'e' || s[i] == 'E')){ret = scanSign(s, ++i) && ret;//e的前后必须都要有数据,并且e后面可以存在正负号,所以需要过滤正负号}while(s[i] == ' ')++i;//因为空格只能出现在末尾和首部,过滤空格return ret && (i == s.size());//当e后面有数据,并且字符串全部走完,说明数据成立}
};

表示数值的字符串(有限状态自动机与搜索)相关推荐

  1. 有限状态自动机java实现_用java开发编译器之:Thompson构造,将正则表达式转换为有限状态自动机...

    阅读博客的朋友可以到我的网易云课堂中,通过视频的方式查看代码的调试和执行过程: 上一节,我们通过代码,实现了一个有限状态自动机,并将其应用于对整形和浮点数的识别.构造有限状态自动机,并驱动它,从而实现 ...

  2. 剑指offer之表示数值的字符串

    题目 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.141 ...

  3. 用java开发编译器之:Thompson构造,将正则表达式转换为有限状态自动机

    阅读博客的朋友可以到我的网易云课堂中,通过视频的方式查看代码的调试和执行过程: http://study.163.com/course/courseMain.htm?courseId=10028300 ...

  4. 第十二篇:形式语言理论与有限状态自动机

    目录 我们到目前已经介绍了什么? 形式语言理论 为什么要去做这个事情 ? 例子 超越会员问题-- 大纲 常规语言/正则语言 例子重现 正则语言的特性 有限状态接受器 样例 派生形态学 形态学 FSA ...

  5. 【Codeforces 506E】Mr.Kitayuta’s Gift【BZOJ 4214】黄昏下的礼物 dp转有限状态自动机+矩阵乘法优化...

    神题-- 胡乱讲述一下思维过程-- 首先,读懂题. 然后,转化问题为构造一个长度为|T|+n的字符串,使其内含有T这个子序列. 之后,想到一个简单的dp.由于是回文串,我们就增量构造半个回文串,设f( ...

  6. 一.正则表达式转换为有限状态自动机:正则表达式转NFA

    原文:https://study.163.com/course/courseMain.htm?courseId=1002830012 一.有限状态自动机的分类 有限状态自动机,其实可以分成两类.第一类 ...

  7. python 数值型字符串实现四舍五入 decimal_Python将科学计数法数值转换为指定精度浮点数...

    Python将科学计数法数值转换为指定精度浮点数 In [20]:money = 1190000.0 In [21]: traded_maket_value = 13824000000 In [22] ...

  8. 剑指offer:面试题20. 表示数值的字符串

    题目:表示数值的字符串 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100"."5e2"."-123".&q ...

  9. (剑指Offer)面试题54:表示数值的字符串

    题目: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.14 ...

最新文章

  1. 计算机操作培训主持词,魅力女性沙龙会主持词文稿.docx
  2. 转 Hystrix入门指南 Introduction
  3. php调mysql接口头文件_php基础系列:PHP连接MySQL数据库用到的三种API
  4. linux交换分区的文件格式为,LINUX的交换分区或交换文件SWAP的查看与维护
  5. python函数返回none_Python 函数默认返回None的原因
  6. java基础面试题之:普通类和抽象类有哪些区别?
  7. mysql1045错误解读_谈谈MYSQL ERROR 1045 错误的解决办法!
  8. pro android学习笔记,【转】Pro Android学习笔记(一):Android 平台 2013.6.4
  9. 阿里云公布IP地理位置库抄袭调查结果;华为云电脑8月16日将停止服务和运营;Chrome 92发布|极客头条...
  10. 来到深圳奋斗的这些年(不断更新!)
  11. 如何给Exadata数据库一体机打补丁patching图解
  12. Android实战开发-Kotlin教程(入门篇 1.0)
  13. Java 就业培训教程 第二章读书笔记啊
  14. 简单易懂的贝叶斯公式
  15. C语言实现矩阵卷积运算
  16. matlab gui制作,MATLAB GUI制作教程
  17. 在线作图|2分钟绘制一张相关性桑基图
  18. C语言入门题库——求2+22+222+......+22222的值
  19. 热释电人体感应红外报警器设计 - 没人取消报警
  20. App Store Review Guidelines中文版-上部

热门文章

  1. mysql数据库开启远程连接_安装MySQL数据库并开启远程访问
  2. java8 list 去重_Java8-Stream在集合中的8种应用案例
  3. 【转】17.Qt界面布局管理详解
  4. 24组合模式(Composite Pattern)
  5. [你必须知道的.NET]第十六回:深入浅出关键字---using全接触
  6. 【转】3.2SharePoint服务器端对象模型 之 访问文件和文件夹(Part 2)
  7. 【转】2.3SharePoint服务器端对象模型 之 访问网站和列表数据(Part 3)
  8. mysql系列:加深对脏读、脏写、可重复读、幻读的理解
  9. 查找字符位置_如何使用find函数和search函数精确查找字符
  10. CCIE-LAB-第一篇-教学导入环境