-
Notifications
You must be signed in to change notification settings - Fork 126
/
Copy pathL0065_ValidNumber.java
177 lines (161 loc) · 6.4 KB
/
L0065_ValidNumber.java
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
* https://leetcode.cn/problems/valid-number/
*
* 有效数字(按顺序)可以分成以下几个部分:
* 1. 一个 小数 或者 整数
* 2.(可选)一个 'e' 或 'E' ,后面跟着一个 整数
*
* 小数(按顺序)可以分成以下几个部分:
* 1.(可选)一个符号字符('+' 或 '-')
* 2. 下述格式之一:
* 1. 至少一位数字,后面跟着一个点 '.'
* 2. 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
* 3. 一个点 '.' ,后面跟着至少一位数字
*
* 整数(按顺序)可以分成以下几个部分:
* 1.(可选)一个符号字符('+' 或 '-')
* 2. 至少一位数字
*
* 部分有效数字列举如下:["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
*
* 提示:
* 1 <= s.length <= 20
* s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,或者点 '.' 。
*/
public class L0065_ValidNumber {
public boolean isNumber(String s) {
// 状态机的状态定义
int STATE_INITIAL = 0; // 初始状态
int STATE_SIGN1 = 1; // 符号状态(整数/小数部分)
int STATE_INTEGER1 = 2; // 整数部分
int STATE_POINT1 = 3; // 小数点(前有整数)
int STATE_POINT2 = 4; // 小数点(前无整数)
int STATE_FRACTION = 5; // 小数部分
int STATE_EXP = 6; // 指数标记
int STATE_SIGN2 = 7; // 符号状态(指数部分)
int STATE_INTEGER2 = 8; // 指数部分
int state = STATE_INITIAL; // 当前状态
for (char c : s.toCharArray()) {
switch (state) {
case 0: // 初始状态
if (c == '+' || c == '-') {
state = STATE_SIGN1;
} else if (Character.isDigit(c)) {
state = STATE_INTEGER1;
} else if (c == '.') {
state = STATE_POINT2;
} else {
return false;
}
break;
case 1: // 符号状态(整数/小数部分)
if (Character.isDigit(c)) {
state = STATE_INTEGER1;
} else if (c == '.') {
state = STATE_POINT2;
} else {
return false;
}
break;
case 2: // 整数部分
if (Character.isDigit(c)) {
state = STATE_INTEGER1;
} else if (c == '.') {
state = STATE_POINT1;
} else if (c == 'e' || c == 'E') {
state = STATE_EXP;
} else {
return false;
}
break;
case 3: // 小数点(前有整数)
if (Character.isDigit(c)) {
state = STATE_FRACTION;
} else if (c == 'e' || c == 'E') {
state = STATE_EXP;
} else {
return false;
}
break;
case 4: // 小数点(前无整数)
if (Character.isDigit(c)) {
state = STATE_FRACTION;
} else {
return false;
}
break;
case 5: // 小数部分
if (Character.isDigit(c)) {
state = STATE_FRACTION;
} else if (c == 'e' || c == 'E') {
state = STATE_EXP;
} else {
return false;
}
break;
case 6: // 指数标记
if (c == '+' || c == '-') {
state = STATE_SIGN2;
} else if (Character.isDigit(c)) {
state = STATE_INTEGER2;
} else {
return false;
}
break;
case 7: // 符号状态(指数部分)
if (Character.isDigit(c)) {
state = STATE_INTEGER2;
} else {
return false;
}
break;
case 8: // 指数部分
if (Character.isDigit(c)) {
state = STATE_INTEGER2;
} else {
return false;
}
break;
}
}
// 判断最终状态是否合法
return state == STATE_INTEGER1 || state == STATE_POINT1 ||
state == STATE_FRACTION || state == STATE_INTEGER2;
}
public static void main(String[] args) {
L0065_ValidNumber solution = new L0065_ValidNumber();
// 测试用例 1:有效数字
String[] validNumbers = {
"2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10",
"-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"
};
System.out.println("测试有效数字:");
for (String num : validNumbers) {
System.out.println(num + " -> " + solution.isNumber(num));
}
System.out.println();
// 测试用例 2:无效数字
String[] invalidNumbers = {
"abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"
};
System.out.println("测试无效数字:");
for (String num : invalidNumbers) {
System.out.println(num + " -> " + solution.isNumber(num));
}
}
}