acwing 31等价于LeetCode 65 有效数字
功能上类似于leetcode 8
/*
思路1:模拟法
方法1:两段法,以e/E为分界点
方法2:三段法,以.和e/E为分界点
思路2:正则表达式
思路3:有限确定状态机DFA
正则文法、正则表达式、DFA可以相互转化。
https://leetcode-cn.com/problems/valid-number/solution/biao-qu-dong-fa-by-user8973/
*/
/*思路1-1 模拟法*/
class Solution {
public:
bool isNumber(string s) {
size_t e_pos = s.find('e');
if (e_pos == string::npos)
e_pos = s.find('E');
if (e_pos == string::npos)
return isPureNumber(s.substr(0, e_pos), false);
return isPureNumber(s.substr(0, e_pos), false)
&& isPureNumber(s.substr(e_pos + 1), true);
}
bool isPureNumber(const string &s, bool no_dot) {
// 返回值代表是否包含数字
// no_dot为ture,s中不能含有dot
if (s.empty()) return false;
int st = int(s[0]=='+' || s[0]=='-');
bool has_digit = false;
for (int i = st; i < s.size(); i ++) {
if (s[i]=='.') {
if (no_dot) return false;
no_dot = true;
}
else if (isdigit(s[i])) has_digit = true;
else return false;
}
return has_digit;
}
};
/*思路1-2 模拟法*/
class Solution {
public:
bool isNumber(string s) {
int i = 0;
while (i < s.size() && s[i] == ' ') i ++ ;
bool num1 = false, num2 = false, num3 = true;
num1 = scanInteger(s, i);
if (s[i] == '.') num2 = scanUnsignedInteger(s, ++ i);
if (s[i] == 'e' || s[i] == 'E') num3 = scanInteger(s, ++ i);
while (i < s.size() && s[i] == ' ') i ++ ;
// printf("%d %d %d",num1, num2, num3);
return (num1 || num2) && num3 && i == s.size();
}
bool scanInteger(string& s, int& pos) {
if (s[pos] == '+' || s[pos] == '-') pos ++ ;
return scanUnsignedInteger(s, pos);
}
bool scanUnsignedInteger(string& s, int& pos) {
int p = pos;
while (pos < s.size() && s[pos] >= '0' && s[pos] <= '9') pos ++ ;
return pos > p;
}
};
/*思路2 正则表达式*/
class Solution {
public:
bool isNumber(string s) {
string pattern = "(\\+|\\-)?((\\d+\\.?)|(\\.?\\d+)|(\\d+\\.\\d+))((e|E)(\\+|\\-)?\\d+)?";
string pattern2 = "(\\+|\\-)?((\\d+)|(\\d+\\.)|(\\.\\d+)|(\\d+\\.\\d+))((e|E)(\\+|\\-)?\\d+)?";
return regex_match(s, regex(pattern));
}
};
/*思路3 DFA*/
class Solution {
public:
bool isNumber(string s) {
if(s.empty()) return false;
int n = s.size();
int state = 0;
vector<bool> finals({0, 0, 0, 1, 0, 1, 1, 0, 1}); // 合法的终止状态
vector<vector<int> > transfer({
{0, 1, 6, 2, -1, -1},
{-1, -1, 6, 2, -1, -1},
{-1, -1, 3, -1, -1, -1},
{8, -1, 3, -1, 4, -1},
{-1, 7, 5, -1, -1, -1},
{8, -1, 5, -1, -1, -1},
{8, -1, 6, 3, 4, -1},
{-1, -1, 5, -1, -1, -1},
{8, -1, -1, -1, -1, -1},
});
for(int i = 0; i < n; ++i) {
state = transfer[state][_make(s[i])];
if(state < 0) return false;
}
return finals[state];
}
private:
int _make(const char& c) {
switch(c) {
case ' ': return 0;
case '+': return 1;
case '-': return 1;
case '.': return 3;
case 'e': return 4;
case 'E': return 4;
default: return _number(c);
}
}
int _number(const char& c) {
if(c >= '0' && c <= '9') return 2;
else return 5;
}
};