LeetCode 65. Valid Number
题目描述:
Validate if a given string is numeric.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.
题目理解与吐槽:
给定一串字符串让你判定是不是数字型的。类似的题在编译原理课上用自动机实现过,就想着直接用自动机就可以了,但是自己把自动机实现的像个残次品,完全是按照字符串的想法去实现的。
如果不再oj上可能效果早已经达到了,但因为是在oj上,所以一些特殊测试用例没想到的情况
比如“1.e2”这就是对的,但是”.e3”就是不对的,反正正常我自己思考,连小数点和e在一起的想法的都没想到。。。
又因为测试用例上没有写正负号,所以我也没有考虑,后面加的时候就草率的加了下。。。
空格问题简直让我崩溃,伤心,本来就不好看的代码,东改改西改改最后简直了。。。
class Solution {
public:
int change(char a){
if(a>='0'&&a<='9'){
return 1;
}else if(a == ' '){
return 0;
}else if(a == 'e'){
return 2;
}else if(a == '.'){
return 3;
}
return 4;
}
bool isNumber(string s) {
int len = s.size();
bool ans=false;
int i=0;
while(i<len){
if(s[i]=='-'||s[i]=='+') {
i++;
int flag = change(s[i]);
if(flag != 1 && flag != 3) break;
}
int flag = change(s[i]);
cout<<flag<<endl;
if(flag == 0) {
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>len) break;
}else if(flag == 1){
while(flag == 1){
i++;
flag = change(s[i]);
}
if(flag == 0){//去除后面的空格
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>=len){//都是整数
ans = true;
}
break;//如果去完空格后面还有内容,就是错的
}
if(i>=len){//都是整数
ans = true;
break;
}else if(flag == 3){//遇到小数点
i++;
flag = change(s[i]);
if(flag == 0){//去除后面的空格
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>=len){//都是整数
ans = true;
}
break;//如果去完空格后面还有内容,就是错的
}
if(i>=len){
ans = true;
break;
}
flag = change(s[i]);
if(flag != 1&&flag!=2) break;//小数点后面接的不是数字也不可以
while(flag == 1){
i++;
flag = change(s[i]);
}
if(flag == 0){//去除后面的空格
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>=len){//都是整数
ans = true;
}
break;//如果去完空格后面还有内容,就是错的
}
if(i>=len) {//111.111型
ans = true;
break;
}else if(flag == 2){//在小数后面遇到e
i++;
if(i>=len)break;
if(s[i]=='+'||s[i]=='-') i++;
flag = change(s[i]);
if(flag != 1) break;
while(flag == 1){
i++;
flag = change(s[i]);
}
if(flag == 0){//去除后面的空格
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>=len){//都是整数
ans = true;
}
break;//如果去完空格后面还有内容,就是错的
}
if(i>=len){//111.11e1111型
ans = true;
break;
}else{
break;
}
}else{
break;
}
}else if(flag == 2){//整数后面遇到e
i++;
if(i>=len)break;
if(s[i]=='+'||s[i]=='-') i++;
flag = change(s[i]);
if(flag != 1) break;
while(flag == 1){
i++;
flag = change(s[i]);
}
if(flag == 0){//去除后面的空格
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>=len){//都是整数
ans = true;
}
break;//如果去完空格后面还有内容,就是错的
}
if(i>=len){//111e1111型
ans = true;
break;
}else{
break;
}
}else{
break;
}
}else if(flag == 3){
i++;
if(i>=len) break;//遇到就结束肯定不可以
flag = change(s[i]);
if(flag != 1) break;//小数点后面接的不是数字也不可以
while(flag == 1){
i++;
flag = change(s[i]);
}
if(flag == 0){//去除后面的空格
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>=len){//都是整数
ans = true;
}
break;//如果去完空格后面还有内容,就是错的
}
if(i>=len) {//111.111型
ans = true;
break;
}else if(flag == 2){//在小数后面遇到e
i++;
if(i>=len)break;
if(s[i]=='+'||s[i]=='-') i++;
flag = change(s[i]);
if(flag != 1) break;
while(flag == 1){
i++;
flag = change(s[i]);
}
if(flag == 0){//去除后面的空格
while(flag == 0){
i++;
flag = change(s[i]);
}
if(i>=len){//都是整数
ans = true;
}
break;//如果去完空格后面还有内容,就是错的
}
if(i>=len){//.11e1111型
ans = true;
break;
}else{
break;
}
}else{
break;
}}
else{
break;
}
}
return ans;
}
};
总结:
看别人的优秀代码是将自动机用二维数组来实现了,一会儿试验一下。
先将优秀代码放在这里:
class Solution {
public:
bool isNumber(string s) {
enum InputType {
INVALID, // 0
SPACE, // 1
SIGN, // 2
DIGIT, // 3
DOT, // 4
EXPONENT, // 5
NUM_INPUTS // 6
};
const int transitionTable[][NUM_INPUTS] = {
-1, 0, 3, 1, 2, -1, // next states for state 0
-1, 8, -1, 1, 4, 5, // next states for state 1
-1, -1, -1, 4, -1, -1, // next states for state 2
-1, -1, -1, 1, 2, -1, // next states for state 3
-1, 8, -1, 4, -1, 5, // next states for state 4
-1, -1, 6, 7, -1, -1, // next states for state 5
-1, -1, -1, 7, -1, -1, // next states for state 6
-1, 8, -1, 7, -1, -1, // next states for state 7
-1, 8, -1, -1, -1, -1, // next states for state 8
};
int state = 0;
for (auto ch : s) {
InputType inputType = INVALID;
if (isspace(ch))
inputType = SPACE;
else if (ch == '+' || ch == '-')
inputType = SIGN;
else if (isdigit(ch))
inputType = DIGIT;
else if (ch == '.')
inputType = DOT;
else if (ch == 'e' || ch == 'E')
inputType = EXPONENT;
// Get next state from current state and input symbol
state = transitionTable[state][inputType];
// Invalid input
if (state == -1) return false;
}
// If the current state belongs to one of the accepting (final) states,
// then the number is valid
return state == 1 || state == 4 || state == 7 || state == 8;
}
};
加加油。。。。