牛客网剑指offer之表示数值的字符串
2020-06-05 06:02
120 查看
题目描述:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
这是牛客网上剑指offer专栏的一道题 事实上自己之前刷leetcode的时候也遇到了这道题 当时觉得情况太复杂 直接看的题解 题解中有人提到了有限状态机的做法 自己直接被名字吓到了(事实上没那么可怕。。) 直接复制提交也没细看具体做法 后来自己刷题过程中又遇到了一些用有限状态机解决的问题 也算是对有限状态机有了初步的了解 这次再次遇到这道题 尝试用有限状态机解决 最后还做了出来 这里交代一下做法
我们用肉眼判断字符串可不可以转化为数字的时候 其实就暗含了一些规则 比如
12e+4.3 不能转化为数值 因为e之后不能跟小数;
1.2.3 不能转化为数值 因为出现了两次 ‘.’;
12e 不能转化为数值 因为出现了e,那么后面就一定要有整数;
按照字符的具体位置 其可以分为九种状态,分别是:
status: 1:start //最初状态 2:+ -符号 3:e/E之前的整数位 4:e之前的小数点位 5:e之前的小数位 6:e/E 7:e之后的+ -符号 8:e之后的数字 9:end 其中状态可以按照以下规则转化: 1->2/3/4/*字符串最开始只能是2、3、4三种状态 否则就是false 值得注意的是 数值可以以小数点开始 比如.34就代表0.34*/ 2->3/4 //+ -符号后面可以跟数字 也可以跟小数点(理由同上) 3->3/4/6/9 //整数后可以继续是整数、小数点、e/E或者直接结束 4->5 //小数点之后只能跟小数位 5->6/9//小数位后可以跟 e/E或者直接结束 6->7/8 // e/E之后可以跟+ -符号 或者数字 7->8 //符号后面跟数字 8->8/9 //数字后面跟数字 或者直接结束
以上状态划分有几点要注意
为什么在 e/E之前要把数字分为 整数位和小数位两种状态呢 e/E之后就不分了呢?
因为 整数位可以跟 小数点 而小数位 是不能的 防止出现 1.2.3 这种情况 而e/E之后是不会存在小数点的;
下面是具体实现代码:
public class Solution { //判断是否是数字 public boolean isNum(char c) { return c>='0'&&c<='9'; } public boolean isNumeric(char[] str) { //一开始是状态“1” String status="1"; //根据当前状态以及当前字符 更新下一状态 for(int i=0;i<str.length;i++) { char c=str[i]; switch(status) { case "1": { if(c=='+'||c=='-') status="2"; else if(isNum(c)) status="3"; else if(c=='.') status="4"; else return false; break; } case "2": { if(isNum(c)) status="3"; else if(c=='.') status="4"; else return false; break; } case "3": { if(isNum(c)) status="3"; else if(c=='.') status="4"; else if(c=='e'||c=='E') status="6"; else return false; break; } case "4": { if(isNum(c)) status="5"; else return false; break; } case "5": { if(isNum(c)) status="5"; else if(c=='e'||c=='E') status="6"; else return false; break; } case "6": { if(c=='+'||c=='-') status="7"; else if(isNum(c)) status="8"; else return false; break; } case "7": { if(isNum(c)) status="8"; else return false; break; } case "8": { if(!isNum(c)) return false; break; } default: return false; } //当前字符为最后一位 且当前状态为“3” “5” “8”时 返回true if(i==str.length-1&&(status.equals("3")||status.equals("5")||status.equals("8"))) return true; } return false; } }
不过上面状态划分是还有一点儿瑕疵 无法解决 +001.5这种情况 也就是没有考虑无意义0的情况 如果考虑的话 要麻烦一点儿 因为通过了所有测试样例 所以也懒得搞了 我估计这道题要考察的可能就是这种思想吧
相关文章推荐
- 剑指offer——53.表示数值的字符串
- 剑指offer--53.表示数值的字符串
- 【剑指offer】面试题20:表示数值的字符串
- 剑指offer——面试题54:表示数值的字符串
- 剑指offer 表示数值的字符串
- 【剑指Offer】54、表示数值的字符串
- 剑指offer-表示数值的字符串
- 【剑指offer——JAVA实现】表示数值的字符串(含思路解答示意图)
- 剑指offer-表示数值的字符串
- 剑指offer(56):表示数值的字符串
- 剑指offer-表示数值的字符串
- 剑指offer-[表示数值的字符串]-JavaScript实现
- 【剑指offer】表示数值的字符串 -- Python 实现
- 剑指offer 表示数值的字符串
- 剑指offer--表示数值的字符串
- 剑指Offer 面试题20:表示数值的字符串 Java代码实现
- 剑指offer(50)-表示数值的字符串
- 17表示数值的字符串--剑指offer,java版
- 剑指Offer——表示数值的字符串
- 剑指offer---表示数值的字符串