DFA和NFA识别串的两道编程题
2013-11-08 15:09
246 查看
题目描述:
![](http://img.blog.csdn.net/20131108140242656?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGFsZXd6bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
根据DFA特点:
(1)没有空串上的转换
(2)对于任意状态s,和输入符号a,只有一条标号为a的边离开s
那么只要构造好状态转换表,那么只要判断转化后的最终判断是不是接受状态就可以了
NFA 的题目描述
![](http://img.blog.csdn.net/20131108150536218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGFsZXd6bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
NFA的难度在于不确定性,同一个输入符号,可能到达不同的状态(包括空串)
所以需要ε闭包,求闭包需要注意,当你从状态a,经过 ε 转换到达b,但是b有可能经过ε转化,到达其它的状态
主要处理思路和DFA类似,不过DFA每次输入都得到的是一个状态,而在NFA中是一个状态集合
伪代码如下:
![](http://img.blog.csdn.net/20131108150721890?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGFsZXd6bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
注意左边S和右边S的不同,分别代表新旧状态
详见代码
,
根据DFA特点:
(1)没有空串上的转换
(2)对于任意状态s,和输入符号a,只有一条标号为a的边离开s
那么只要构造好状态转换表,那么只要判断转化后的最终判断是不是接受状态就可以了
#include<iostream> #include<cstdlib> #include<memory.h> #include<string> using namespace std; #define N 51 #define M 27 int trans [M]; int acc ; int count_; bool isAc(int fin_st) { for(int i=0; i<count_; i++) if(acc[i]==fin_st) return true; return false; } int main() { int n,m,i,j; int start; while(cin>>n>>m &&(n!=0 && m!=0)) { memset(trans,0,sizeof(trans)); memset(acc,0,sizeof(acc)); for( i=1; i<=n; i++) for(j=1; j<=m; j++) cin>>trans[i-1][j]; count_=0; while(cin>>acc[count_++] && acc[count_-1]!=-1){;} count_--; string query; while(cin>>query && query!="#") { start=0; for(i=0; i<query.length(); i++) start=trans[start][query[i]-'a'+1]; if(isAc(start)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } }
NFA 的题目描述
NFA的难度在于不确定性,同一个输入符号,可能到达不同的状态(包括空串)
所以需要ε闭包,求闭包需要注意,当你从状态a,经过 ε 转换到达b,但是b有可能经过ε转化,到达其它的状态
主要处理思路和DFA类似,不过DFA每次输入都得到的是一个状态,而在NFA中是一个状态集合
伪代码如下:
注意左边S和右边S的不同,分别代表新旧状态
详见代码
#include<iostream> #include<cstdlib> #include<cstdio> #include<memory.h> #include<string> #include<string.h> #include<vector> #include<stack> #include<algorithm> using namespace std; #define N 51 #define M 27 vector<int> move_ [M]; int acc ; int count_,n,m;//n is states, m is alp num bool flag ; bool isAc( stack<int> &fin) { while(!fin.empty()){ for(int j=0; j<count_; ++j) if(acc[j]==fin.top()) return true; fin.pop(); } return false; } void clousre( stack<int> &ans,int m) { vector<int> stack_(move_[m][0]); flag[ m]=1; ans.push(m); for(int i=0; i<stack_.size(); ++i) { if(! flag[ move_[m][0][i] ] ) clousre(ans, move_[m][0][i] ); } } int get_num(char * str,int &index) { int sum,i; sum=0; for(;(str[index]<='9')&& (str[index]>='0');index++) { sum=sum*10+str[index]-'0'; } index--; return sum; } int main() { int i,j,value,k,h; stack<int> oldState,newState; char line[500]; char *ps; char lash; while(scanf("%d %d%c",&n,&m,&lash) &&(n!=0 && m!=0)) { memset(move_,0,sizeof(move_)); memset(acc,0,sizeof(acc)); for( i=0; i<n; i++) { gets(line); h=0; ps=line; for(j=1; j<=m; j++){ for(;(line[h]!='}')&&(line[h]!='\0'); h++) { if(line[h]<='9' && line[h]>='0'){ value=get_num(line,h); move_[i][j-1].push_back(value); } } h++; } } count_=0;//the number of accept state while(cin>>acc[count_++] && acc[count_-1]!=-1){;} count_--; string query; while(cin>>query && query!="#") { memset(flag,0,sizeof(flag)); clousre(newState,0); for(i=0; i<query.length(); i++) { while(!newState.empty()){ oldState.push(newState.top()); flag[newState.top()]=0; newState.pop(); } //s(left)=s(right); while(!oldState.empty()){ // start=trans[start][query[i]-'a'+1]; for(k=0; k<move_[ oldState.top() ][ query[i]-'a'+1 ].size(); ++k) { if(!flag[ move_[ oldState.top() ][ query[i]-'a'+1 ][k] ]) clousre( newState, move_[ oldState.top() ][ query[i]-'a'+1 ][k] ); } oldState.pop(); } } if(isAc(newState)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } }
,
相关文章推荐
- NFA转DFA - json数字识别
- 2017滴滴实习招聘笔试两道编程题
- <编译原理>NFA转化DFA 及 DFA的化简
- 编译原理学习周入门教程--(9)编译程序第一个工作阶段-词法分析(NFA和DFA转换) .
- NFA与DFA
- 两道网易ttt编程题
- 2017年暑期实习生招聘(百度)——两道编程题
- 【直接NFA->DFA】
- NFA和DFA区别
- 编译原理 NFA_DFA代码实现 bfs+dfs+状态压缩 伪代码
- Transform Regex to NFA/DFA -- Thompson Algorithm
- 词法分析器2(ε-NFA到DFA的转换)
- 软考进行时——DFA和NFA
- [编程题]识别有效的IP地址和掩码并进行分类统计
- 两道函数式编程题
- DFA与NFA
- [C/C++]2009年华为软件设计大赛两道编程题
- 两道笔试编程题(求水仙数和求平方根数组之和)
- 【直接NFA->DFA】易错点
- DFA 和 NFA 的区别