目录
(表格分析)
方法:有穷自动机FA算法
有穷自动机FA的输入需要两个参数:当前状态和字符
一、判断流程
使用switch-case语句完成状态的选择
状态state | 此时字符 | 后面可以出现的字符 |
1 | 初始状态,无字符 | 正负号 、数字 |
2 | 正负号 | 数字 |
3 | 数字 | 数字、小数点、e/E |
4 | 小数点 | 数字 |
5 | 小数点后一位数字 | 数字、e/E、结束 |
6 | e/E | 正负号、数字 |
7 | e/E后一位数字 | 数字、结束 |
8 | e/E后一位正负号 | 数字 |
default:除了表中出现的情况,其他出现的字符都错误,均可return -1。
在字符串的for循环中,递归调用fa函数,使其状态不断向下延续判断,当出现错误状态时,即跳出循环。
- 当循环结束后,若状态state==0,则代表字符串扫描完成且无误,故输出yes;
- 若在FA识别的任何一个步骤出现错误,则FA函数会返回-1,结束for循环,输出no;
关键语句:
state=FA(state,c);
所需函数:
int digit(char); ///判断是否为数字位
int FA(state,char);
二、代码示例
#include<iostream>
#include<string>
using namespace std;
int digit(char c){
if(c>='0'&&c<='9') return 1;
else return 0;
}
int FA(int n,char c){
switch(n){
case 1:
if(c=='+'||c=='-') return 2;
if(digit(c)) return 3;
return -1;
case 2:
if(digit(c)) return 3;
return -1;
case 3:
if(digit(c)) return 3;
if(c=='.') return 4;
if(c=='e'||c=='E') return 5;
return -1;
case 4:
if(digit(c)) return 6;
return -1;
case 5:
if(c=='-'||c=='+') return 8;
if(digit(c)) return 7;
return -1;
case 6:
if(digit(c)) return 6;
if(c=='\0') return 0;
if(c=='e'||c=='E') return 5;
return -1;
case 7:
if(digit(c)) return 7;
if(c=='\0') return 0;
return -1;
case 8:
if(digit(c)) return 7;
return -1;
default:
return -1;
}
}
int main(){
string s;
int n,i,state;
cin>>s;
n=s.length();state=1;
for(i=0;i<=n;i++){
state=FA(state,s[i]);
if(state==-1){
break;
}
}
if(state==0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
三、代码易错点
- 字符串扫描的for循环n要<=字符串的长度,n==s[i]时s[i]=='\0'
- 有穷自动机的状态转换需要注意,小数点后面的数字和e\E后面的数字都要单独拿出来进行讨论