剑指 Offer 20. 表示数值的字符串 + 有限状态自动机
剑指 Offer 20. 表示数值的字符串
Offer 20
常规解法:
- 题目解题思路:需要注意几种情况:
- 输入的字符串前后可能有任意多个空格,这是合法的。
- 正负号:
(1)正负号只能出现一次。
(2)正负号后面一个字符必须是数字或者小数点。
(3)字符串中最多有两个正负号(正常情况下最多只有一个,但是这里有指数E的情况,其前后可以加正负号)。 - e或者E:
(1) 指数符号最多出现一次。
(2) 前一个字符必须是数字或者小数点,如果是小数点,则小数点不能出现在第一个字符的位置。
(3) 后一个字符必须是数字或者正负号。
(4) 后面的所有字符中不能包含小数点,而前面可以包含小数点。 - 小数点:
(1) 小数点最多出现一次(不论是否是指数的形式)。
(2) 小数点如果出现在最后,则其前一个字符必须是数字符号。
(3) 小数点不能出现在E或e的后面。
package com.walegarrett.offer;
/**
* @Author WaleGarrett
* @Date 2021/1/26 17:59
*/
/**
* 题目描述:
* 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"-1E-16"、"0123"都表示数值,
* 但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。
*/
public class Offer_20 {
public boolean isNormal(String s){
int index = 0;
if(s == null || s.equals(""))
return false;
char start = s.charAt(0);
//数字的首字母必须是+,-,0-9其他的都不符合
if(start != '+' && start != '-' && start != '.' && (start < '0' || start > '9'))
return false;
if(start == '+' || start == '-' || start == '.'){
if(start == '+' || start == '-')
index = 1;
if(s.length() == 1)
return false;
if (s.charAt(1) != '.' && (s.charAt(1) < '0' || s.charAt(1) > '9'))
return false;
else if(s.charAt(1) == '.' && s.length() == 2)
return false;
// if(s.charAt(1) == '.' || s.charAt(1) == 'e')
// return false;
}
//只能有一个小数点,一个+,-符号
if(s.indexOf(".") != s.lastIndexOf(".")
|| s.indexOf("+") != s.lastIndexOf("+")
|| s.indexOf("-") != s.lastIndexOf("-"))
return false;
//不可以同时存在+,-号
if(s.contains("+") && s.contains("-"))
return false;
for(int i = index; i < s.length(); i++){
//除这些特殊字符外的字符都不合法
if (s.charAt(i) != '.' && (s.charAt(i) < '0' || s.charAt(i) > '9'))
return false;
}
//最多只有一个小数点
return s.indexOf(".") == s.lastIndexOf(".");
}
public boolean isNumber(String s) {
s = s.trim();
if(s.contains("e") || s.contains("E")){
int firstIndex, lastIndex;
if(s.contains("e")){
firstIndex = s.indexOf("e");
lastIndex = s.lastIndexOf("e");
}else{
firstIndex = s.indexOf("E");
lastIndex = s.lastIndexOf("E");
}
if(firstIndex != lastIndex)//存在多个e
return false;
else{
if(firstIndex == s.length() -1)//e在最后一个字符
return false;
String before = s.substring(0, firstIndex);//前半部分
String end = s.substring(firstIndex +1);//后半部分
if(!isNormal(before) || !isNormal(end))
return false;
//后半部分不能有小数点
if(end.contains("."))
return false;
}
}else{
if(!isNormal(s))
return false;
}
return true;
}
}
有限状态机:面试题20. 表示数值的字符串(有限状态自动机,清晰图解)

class Solution {
public boolean isNumber(String s) {
Map[] states = {
new HashMap<>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }}, // 0.
new HashMap<>() {{ put('d', 2); put('.', 4); }}, // 1.
new HashMap<>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }}, // 2.
new HashMap<>() {{ put('d', 3); put('e', 5); put(' ', 8); }}, // 3.
new HashMap<>() {{ put('d', 3); }}, // 4.
new HashMap<>() {{ put('s', 6); put('d', 7); }}, // 5.
new HashMap<>() {{ put('d', 7); }}, // 6.
new HashMap<>() {{ put('d', 7); put(' ', 8); }}, // 7.
new HashMap<>() {{ put(' ', 8); }} // 8.
};
int p = 0;
char t;
for(char c : s.toCharArray()) {
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(!states[p].containsKey(t)) return false;
p = (int)states[p].get(t);
}
return p == 2 || p == 3 || p == 7 || p == 8;
}
}
剑指 Offer 20. 表示数值的字符串 + 有限状态自动机的更多相关文章
- 【Java】 剑指offer(20) 表示数值的字符串
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如, ...
- 剑指 Offer 20. 表示数值的字符串
方法:分为几个部分判断 DA[.B][E/eC] D 其中D表示前后的空格,需要处理,跳过即可 A可以带正负号 有符号数 B无符号数 C可以为有符号数(带+-号) 小数点.后面必须是无符号数或者没有 ...
- Go语言实现:【剑指offer】表示数值的字符串
该题目来源于牛客网<剑指offer>专题. 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2",&qu ...
- 剑指offer——22表示数值的字符串
题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1 ...
- 剑指Offer 53. 表示数值的字符串 (字符串)
题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1 ...
- 《剑指offer》-表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1416&q ...
- [剑指Offer] 53.表示数值的字符串
题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1 ...
- [剑指offer] 53. 表达数值的字符串
题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1 ...
- 剑指offer:表示数值的字符串
题目描述: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3. ...
随机推荐
- 【noi 2.6_9265】取数游戏(DP)
题意:从自然数1到N中不取相邻2数地取走任意个数,问方案数. 解法:f[i][1]表示在前i个数中选了第i个的方案数,f[i][0]表示没有选第i个.f[i][1]=f[i-1][0]; f[i][ ...
- HDU 6880 Permutation Counting dp
题意: 给你一个n和一个长度为n-1的由0/1构成的b序列 你需要从[1,n]中构造出来一个满足b序列的序列 我们设使用[1,n]构成的序列为a,那么如果ai>ai+1,那么bi=1,否则bi= ...
- HDU 2176 取(m堆)石子游戏 && HDU1850 Being a Good Boy in Spring Festivaly
HDU2176题意: m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子. 通过 SG定理 我们可以知道每一个数的SG值,等于这个数到达不了的前面数 ...
- Codeforces Round #680 (Div. 2, based on Moscow Team Olympiad) D. Divide and Sum (思维,数学,逆元)
题意:有一个长度为\(2n\)数组,从中选分别选\(n\)个元素出来组成两个序列\(p\)和\(q\),(\(p\)和\(q\)中只要有任意一个元素在\(a\)的原位置不同,就算一个新的情况),选完后 ...
- 国产网络测试仪MiniSMB - 如何3秒内创建出16,000条IP递增流
国产网络测试仪MiniSMB(www.minismb.com)是复刻smartbits的IP网络性能测试工具,是一款专门用于测试智能路由器,网络交换机的性能和稳定性的软硬件相结合的工具.可以通过此以太 ...
- k8s二进制部署 - coredns安装
coredns的资源清单文件rabc.yaml apiVersion: v1 kind: ServiceAccount metadata: name: coredns namespace: kube- ...
- GoAccess 监控工具
GoAccess 基本概述 简易的统计访问量的软件,官方安装教程 GoAccess 安装 # 下载包 [root@web01 ~]# wget http://tar.goaccess.io/goacc ...
- Codeforces13C–Sequence (区间DP)
题目大意 给定一个含有N个数的序列,要求你对一些数减掉或者加上某个值,使得序列变为非递减的,问你加减的值的总和最少是多少? 题解 一个很显然的结果就是,变化后的每一个值肯定是等于原来序列的某个值,因为 ...
- hdu-1159 1087 1257(dp)
本文就最长公共子序列,最长连续递增子序列的长度,最大连续递增子序列的值进行对比. hdu-1159: Common Subsequence Time Limit: 2000/1000 MS (Java ...
- 杭电多校HDU 6601 Keen On Everything But Triangle(主席树)题解
题意: 有\(n\)根长度不一的棍子,q次询问,求\([L,R]\)区间的棍子所能组成的周长最长的三角形.棍长\(\in [1, 1e9]\),n\(\in [1, 1e5]\). 思路: 由于不构成 ...