LeetCode 65. 有效数字(有限状态机正则)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 65. 有效数字(有限状态机正则)相关的知识,希望对你有一定的参考价值。
65. 有效数字
2021.6.17每日一题
题目描述
有效数字(按顺序)可以分成以下几个部分:
一个 小数 或者 整数
(可选)一个 'e' 或 'E' ,后面跟着一个 整数
小数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-')
下述格式之一:
至少一位数字,后面跟着一个点 '.'
至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
一个点 '.' ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-')
至少一位数字
部分有效数字列举如下:
["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]
部分无效数字列举如下:
["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]
给你一个字符串 s ,如果 s 是一个 有效数字 ,请返回 true 。
示例 1:
输入:s = "0"
输出:true
示例 2:
输入:s = "e"
输出:false
示例 3:
输入:s = "."
输出:false
示例 4:
输入:s = ".1"
输出:true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
有限状态机,剑指offer20题写过
class Solution {
public boolean isNumber(String s) {
//一种直接if的方法,一种有限状态机吧
//开始状态,能转移到“整数部分的数字数字,.,+/-” 0
//左侧有整数的小数点,能转移到小数部分的数字,e,结束 1
//整数部分的数字,能转移到e,左侧有整数的小数点,结束,整数部分的数字 2
//+/-,能转移到数字,左侧无整数的小数点 3
//左侧无整数的小数点,能转移到小数部分的数字, 4
//小数部分的数字,能转移到小数部分的数字,e,结束 5
//e,能转移到指数数字,指数符号+/- 6
//指数符号+/-,能转移到指数数字 7
//指数数字,能转移到指数数字,结束 8
Map[] states = {
new HashMap<>(){{ put('d', 2); put('s', 3); put('.', 4); }}, //0,开始状态
new HashMap<>(){{ put('d', 5); put('e', 6); }}, //1,左侧有整数的小数点
new HashMap<>(){{ put('d', 2); put('e', 6); put('.', 1); }}, //2,整数部分的数字
new HashMap<>(){{ put('d', 2); put('.', 4); }}, //3,+/-
new HashMap<>(){{ put('d', 5); }}, //4,左侧无整数的小数点
new HashMap<>(){{ put('d', 5); put('e', 6); }}, //5,小数部分的数字
new HashMap<>(){{ put('d', 8); put('s', 7); }}, //6,e
new HashMap<>(){{ put('d', 8); }}, //7,指数符号+/-
new HashMap<>(){{ put('d', 8); }} //8,指数数字
};
//刚开始在状态0
int p = 0;
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
char t;
if(c >= '0' && c <= '9') t = 'd';
else if(c == '+' || c == '-') t = 's';
else if(c == '.') t = '.';
else if(c == 'e' || c == 'E') t = 'e';
else
t = '?';
//如果不包含这个状态,直接false
if(!states[p].containsKey(t))
return false;
//状态转移
p = (int)states[p].get(t);
}
return p == 1 || p == 2 || p == 5 || p == 8;
}
}
学了正则,来试着用正则表达式写一下:
import java.util.regex.Pattern;
class Solution {
public boolean isNumber(String s) {
//正负号可出现可不出现
//然后是数字.,数字.数字或者.数字
//然后指数部分可有可无
//指数部分,就是e/E[+-]?\\\\d+
Pattern pattern = Pattern.compile("[+-]?((\\\\d+\\\\.\\\\d*)|(\\\\.?\\\\d+))([eE][+-]?\\\\d+)?");
return pattern.matcher(s).matches();
}
}
也可以写成一张表,学习一下:
class Solution {
public int make(char c) {
switch(c) {
case ' ': return 0;
case '+':
case '-': return 1;
case '.': return 3;
case 'e': return 4;
default:
if(c >= 48 && c <= 57) return 2;
}
return -1;
}
public boolean isNumber(String s) {
int state = 0;
int finals = 0b101101000;
int[][] transfer = new int[][]{{ 0, 1, 6, 2,-1},
{-1,-1, 6, 2,-1},
{-1,-1, 3,-1,-1},
{ 8,-1, 3,-1, 4},
{-1, 7, 5,-1,-1},
{ 8,-1, 5,-1,-1},
{ 8,-1, 6, 3, 4},
{-1,-1, 5,-1,-1},
{ 8,-1,-1,-1,-1}};
char[] ss = s.toCharArray();
for(int i=0; i < ss.length; ++i) {
int id = make(ss[i]);
if (id < 0) return false;
state = transfer[state][id];
if (state < 0) return false;
}
return (finals & (1 << state)) > 0;
}
}
作者:user8973
链接:https://leetcode-cn.com/problems/valid-number/solution/biao-qu-dong-fa-by-user8973/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三叶姐的模拟,思路就是根据e/E将字符串分成两部分,然后判断两部分是否为整数或者浮点数
class Solution {
public boolean isNumber(String s) {
int n = s.length();
char[] cs = s.toCharArray();
int idx = -1;
for (int i = 0; i < n; i++) {
if (cs[i] == 'e' || cs[i] == 'E') {
if (idx == -1) idx = i;
else return false;
}
}
boolean ans = true;
if (idx != -1) {
ans &= check(cs, 0, idx - 1, false);
ans &= check(cs, idx + 1, n - 1, true);
} else {
ans &= check(cs, 0, n - 1, false);
}
return ans;
}
boolean check(char[] cs, int start, int end, boolean mustInteger) {
if (start > end) return false;
if (cs[start] == '+' || cs[start] == '-') start++;
boolean hasDot = false, hasNum = false;
for (int i = start; i <= end; i++) {
if (cs[i] == '.') {
if (mustInteger || hasDot) return false;
hasDot = true;
} else if (cs[i] >= '0' && cs[i] <= '9') {
hasNum = true;
} else {
return false;
}
}
return hasNum;
}
}
作者:AC_OIer
链接:https://leetcode-cn.com/problems/valid-number/solution/gong-shui-san-xie-zi-fu-chuan-mo-ni-by-a-7cgc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以上是关于LeetCode 65. 有效数字(有限状态机正则)的主要内容,如果未能解决你的问题,请参考以下文章