发布于 

剑指 Offer.20-表示数值的字符串

剑指 Offer.20-表示数值的字符串

题目链接

剑指 Offer 20. 表示数值的字符串

问题描述

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)

个人想法(模拟)

根据不能通过的测试用例,反复修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
class Solution {
public boolean isNumber(String s) {
boolean res = true;
// 1.去除首尾的空格
String str = s.trim();
// 将字符串中字符转小写
str = str.toLowerCase();
// 2.尝试将当前的字符串通过e,E进行拆分
int eNumber = 0;
for(char c:str.toCharArray()){
if(c == 'e'){
eNumber++;
}
}
if(eNumber > 1) return false;
String[] strs = str.split("e");
// 当出现两个以上e的时候return false
if(strs.length > 2) return false;
//当能够被切分时
if(strs.length == 2){
// 判断左右两侧是否为整数
for(int i=0;i<2;i++){
res&=arrayIsNumber(strs[i],i);
}
return res;
}else{
// 当数为一个整体时
// 用于统计符号位
int flag = 0;
int conutPoint = 0;
int numberCount = 0;
int kongge = 0;
int flagIndex = -1;
// 符号位 位置合法
for(char c:str.toCharArray()){
if(c == '+' || c == '-'){
flag++;
}
if(c == '.'){
conutPoint++;
}
if(c>=48 && c<=57){
numberCount++;
}
if(c == ' '){
kongge++;
}
}
if(flag > 1 || conutPoint > 1 || numberCount < 1 || kongge > 0) return false;
// 有符号情况
if(flag == 1){
int plusIndex = str.lastIndexOf('+');
if(plusIndex != 0 && plusIndex != -1){
return false;
}
int subIndex = str.lastIndexOf('-');
if(subIndex != 0 && subIndex != -1){
return false;
}
}
// 判断除去符号位以外是否合法
String noFlagNumber = str.replaceAll("\\+","");
noFlagNumber = noFlagNumber.replaceAll("-","");
System.out.println(noFlagNumber);
// 判断当前剩下来的是否为合法数字
for(char c:noFlagNumber.toCharArray()){
if(!((c>=48 && c<=57) || c=='.')){
return false;
}
}
}
return res;
}

//判断传入字符串是否为数字
boolean arrayIsNumber(String s,int i){
//增加对符号的判断
int flag = 0;
int kongge = 0;
int conutPoint = 0;
int numberCount = 0;
if(s.length() == 0) return false;
for(char c:s.toCharArray()){
if(c=='+' || c=='-'){
flag++;
continue;
}
if(c == ' '){
return false;
}
if(!(c>=48 && c<=57)){
if(c == '.'){
conutPoint++;
}else{
return false;
}
}else{
numberCount++;
}
}
if(flag == 1){
int plusIndex = s.lastIndexOf('+');
if(plusIndex != 0 && plusIndex != -1){
return false;
}
int subIndex = s.lastIndexOf('-');
if(subIndex != 0 && subIndex != -1){
return false;
}
}
if(i == 0){
return true & (flag < 2) &(numberCount > 0) & (conutPoint < 2);
}else{
//当为后半部分时候 不能为浮点数
return true & (flag < 2) &(numberCount > 0) & (conutPoint < 1);
}
}
}

官方解法(有限状态自动机)

有明确规则的串识别问题是否都能通过有限状态自动机进行实现?

有限状态自动机在编码上的难度不高,当能够正确画出每一步的状态转移图时,即完成了

Picture1.png

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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;
}
}

作者:jyd
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/solution/mian-shi-ti-20-biao-shi-shu-zhi-de-zi-fu-chuan-y-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @John Doe 创建,使用 Stellar 作为主题。