2025-3-5
最近进行编译原理课程学习,复习部分DA和NDA等计算理论的知识.
考虑利用cpp实现一个简单的面向过程的自动机.
自动机由五元组构成,
1.字符集.此处默认所有字符为char类型,如果想要实现将多个字符看成一个整体,可以用string类型代替.
2.状态转移.状态转移是一个二元输入一元输出的函数,考虑用二维矩阵来实现.其中行为状态编号,列为当前读取的字符.
3.状态集合.可以被包含在状态转移的矩阵中.
4.开始状态.设定特殊输入判断开始即可
5.终止状态.设定bool类型数组,记录终止状态即可.
运行过程:读入字符串后,由初始状态 + 当前字符通过状态转移的矩阵获得下一个状态,直至遍历完整个字符串.最后判断当前状态是不是终止状态即可.
#include<bits/stdc++.h>
using namespace std;
/*
写一个DA自动机
输入:n个状态,状态矩阵(状态,当前值) => 下个状态
输出:可执行的自动机
*/
const int N = 1e3+10;
unordered_map<char,int> mp;
unordered_map<int,char> pm;
int st[N][N];
bool es[N];
int main() {
int n,m;
printf("State size:\n");
scanf("%d",&n);
printf("dictionary size:\n");
scanf("%d",&m);
char tmp;
for (int i =1; i<= m; i++) {
printf("Enter chars %d:\n",i);
cin>>tmp;
mp[tmp] = i;
pm[i] = tmp;
}
for (int i =1; i<= n;i++) {
for (int j = 1; j<= m; j++) {
printf("in %d, find char %c, to:\n",i,pm[j]);
cin>>st[i][j];
}
}
for (int i= 1; i<= n; i++) {
for (int j = 1; j<= m; j++) {
printf("in %d, find char %c, to: %d \n",i,pm[j],st[i][j]);
}
}
int endnum = 0;
printf("How many end states?\n");
scanf("%d",&endnum);
for (int i =1,num; i<= endnum; i++) {
printf("No. %d:",i);
scanf("%d",&num);
es[num] = true;
}
string str;
int testtime = 0;
int star = 0;
printf("which state is your star palce?\n");
scanf("%s",&star);
printf("Enter testTimes:\n");
scanf("%d", &testtime);
while (testtime--){
printf("input your sentence:");
cin>>str;
int len = str.length();
int cur = star;
for (int i =0; i<len; i++) {
cur = st[cur][mp[str[i]]];
}
if (es[cur])
printf("YES.\n");
else
printf("NO.\n");
}
return 0;
}