编译原理 NFA_DFA代码实现 bfs+dfs+状态压缩 伪代码

博客分享了作者在编译原理课程中使用C++实现NFA_DFA转化的过程,包括状态压缩、bfs和dfs算法。作者强调了图像输出的困难,介绍了如何用C#处理输出的txt文件来绘制图形,并提到使用向量法处理箭头绘制。代码已上传至优快云。

这是上个月的作业了,由于当初发怕被抄袭,这个blog现在补上。

编译原理老师给我们布置了一个作业,要求用程序实现NFA_DFA的转化,并且要画图!画图!画图!日狗的事情说三遍!

对于我这个ACMer,输出表格的部分分分钟就编好了,bfs、dfs、状态压缩,程序高效无比,bug基本都清了。看看其他人还字符串比较爆搜的。。。这要是在比赛里不超时才怪!!!然后我们用了10%的时间和精力编了前半部分,用了90%的精力编写图像输出程序。。。

先给大家看看我们的前半部分是咋弄的,我用c++写的。想看代码?大哥打赏打赏use俩积分下载我上传的资源去>_<

http://download.youkuaiyun.com/detail/qdbszsj/9307911

这是伪代码,nb的人有伪代码基本就能敲出来了

1.初始化(init):

声明各种变量,开数组,并清空。

 

2.输入(input):

按照交互界面提示的格式,将nfa图输入。

 

3.运行核心算法程序(bfs宽度优先搜索):

 

声明一个队列q,q内存储int型数据,代表状态压缩后的一个集合;

放入起点0 通过dfs算法(深度优先搜索,具体实现见下文附录)得出的集合a;

在映射s中存入a,key值为a,权值为n++(n起始为1);

While(队列不为空){

      令f=队列的第一个元素;

      队列q.pop掉一个元素;

      统计的集合个数num_of_jihe++;

      for(i从0~图中权值的种类数){

     

以下是使用C++编写的NFA转换DFA代码示例: ``` #include <iostream> #include <vector> #include <set> #include <map> using namespace std; // 定义NFA结构体 struct NFA { int start_state; // 起始状态 vector<int> accept_states; // 接受状态 map<pair<int, char>, vector<int>> transitions; // 转换函数 }; // 定义DFA结构体 struct DFA { set<int> states; // 状态集合 int start_state; // 起始状态 set<int> accept_states; // 接受状态集合 map<pair<int, char>, int> transitions; // 转换函数 }; // 获取NFA中从state状态出发通过symbol转换可以到达的所有状态 vector<int> get_next_states(NFA nfa, int state, char symbol) { vector<int> next_states; if (nfa.transitions.count(make_pair(state, symbol))) { next_states = nfa.transitions[make_pair(state, symbol)]; } return next_states; } // 获取NFA中从state状态出发可以到达的所有状态 set<int> epsilon_closure(NFA nfa, int state) { set<int> closure; closure.insert(state); bool changed = true; while (changed) { changed = false; for (int s : closure) { vector<int> next_states = get_next_states(nfa, s, 'e'); for (int next_state : next_states) { if (closure.count(next_state) == 0) { closure.insert(next_state); changed = true; } } } } return closure; } // 将NFA转换为DFA DFA nfa_to_dfa(NFA nfa) { DFA dfa; // 计算NFA的epsilon闭包 set<int> start_state = epsilon_closure(nfa, nfa.start_state); dfa.states.insert(1); dfa.start_state = 1; if (nfa.accept_states.count(nfa.start_state)) { dfa.accept_states.insert(1); } map<set<int>, int> dfa_state_map; dfa_state_map[start_state] = 1; int curr_dfa_state = 1; set<int> unmarked_dfa_states; unmarked_dfa_states.insert(1); while (!unmarked_dfa_states.empty()) { int dfa_state = *unmarked_dfa_states.begin(); unmarked_dfa_states.erase(unmarked_dfa_states.begin()); set<int> nfa_states = dfa_state_map.inverse[dfa_state]; for (char symbol = 'a'; symbol <= 'z'; symbol++) { set<int> next_states; for (int nfa_state : nfa_states) { set<int> next_nfa_states = epsilon_closure(nfa, nfa_state); for (int next_nfa_state : next_nfa_states) { vector<int> transitions = get_next_states(nfa, next_nfa_state, symbol); for (int transition : transitions) { next_states.insert(transition); } } } if (!next_states.empty()) { int next_dfa_state; if (dfa_state_map.count(next_states)) { next_dfa_state = dfa_state_map[next_states]; } else { curr_dfa_state++; dfa.states.insert(curr_dfa_state); next_dfa_state = curr_dfa_state; dfa_state_map[next_states] = next_dfa_state; if (nfa.accept_states.count(next_states)) { dfa.accept_states.insert(next_dfa_state); } unmarked_dfa_states.insert(next_dfa_state); } dfa.transitions[make_pair(dfa_state, symbol)] = next_dfa_state; } } } return dfa; } int main() { // 定义NFA NFA nfa; nfa.start_state = 0; nfa.accept_states = {2}; nfa.transitions[make_pair(0, 'a')] = {1}; nfa.transitions[make_pair(1, 'b')] = {2}; nfa.transitions[make_pair(0, 'e')] = {3}; nfa.transitions[make_pair(3, 'a')] = {4}; nfa.transitions[make_pair(4, 'b')] = {2}; // 将NFA转换为DFA DFA dfa = nfa_to_dfa(nfa); // 输出DFA cout << "DFA states: "; for (int state : dfa.states) { cout << state << " "; } cout << endl; cout << "DFA start state: " << dfa.start_state << endl; cout << "DFA accept states: "; for (int state : dfa.accept_states) { cout << state << " "; } cout << endl; cout << "DFA transitions: " << endl; for (auto it : dfa.transitions) { cout << " " << it.first.first << " --" << it.first.second << "--> " << it.second << endl; } return 0; } ``` 该代码使用了C++ STL库中的容器类型,如vector、set和map等,以便更方便地实现算法逻辑。在主函数中,我们先定义了一个NFA,然后调用nfa_to_dfa函数将其转换为DFA,并输出DFA的各项属性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值