IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 正则表达式转NFA(C++代码) -> 正文阅读

[C++知识库]正则表达式转NFA(C++代码)

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <stack>
#include <fstream>
using namespace std;

class NFA {
    string name;    // NFA name
    string re;      // 正则表达式    
    string re_;     // 带连接符的正则表达式
    string pe;      // 正则表达式的后缀形式
    int stateNum;   // 状态数
    pair<int, int> se;      // 起点和终点状态编号
    vector<vector<pair<int, char> > > graph;  // NFA状态关系图
public:
    NFA(string name, string re);
    void insertContact();
    int priority(char c);
    void re2Pe();
    int newState();
    void pe2NFA();
    void printNFA(ofstream& fout);
};
NFA::NFA(string name, string re) {
    this->name = name; this->re = re;
    re_ = pe = "";
    stateNum = 0;
    graph.push_back(vector<pair<int, char> >());
}
// 插入连接符 .
void NFA::insertContact() {
    for(int i = 0; i < re.size() - 1; i++) {
        re_ += re[i];
        if(re[i] != '(' && re[i + 1] != ')' && re[i] != '|' && re[i + 1] != '|'
            && re[i + 1] != '*') re_ += '.';
    }
    re_ += re.back();
}
// 运算符优先级
int NFA::priority(char c) {
    if(c == '*') return 3;
    else if(c == '.') return 2;
    else if(c == '|') return 1;
    else return 0;
}
// 正则表达式转换为后缀形式
void NFA::re2Pe() {
    stack<char> op;
    for(auto c : re_) {
        if(c == '(') op.push(c);
        else if(c == ')') {
            while(op.top() != '(') {
                pe += op.top();
                op.pop();
            }
            op.pop();
        }
        else if(c == '*' || c == '.' || c == '|') {
            while(op.size()) {
                if(priority(c) <= priority(op.top())) {
                    pe += op.top();
                    op.pop();
                }
                else break;
            }
            op.push(c);
        }
        else pe += c;
    }
    while(op.size()) {
        pe += op.top();
        op.pop();
    }
}
// 生成新状态
int NFA::newState() {
    graph.push_back(vector<pair<int, char> >());    // 生成新状态的边集
    return ++stateNum;
}
// 后缀转换为NFA
void NFA::pe2NFA() {
    stack<pair<int, int> > states;      // 状态栈
    int s, e;       // 状态边起点和终点状态编号
    for(auto c : pe) {
        if(c != '*' && c != '.' && c != '|') {
            s = newState();
            e = newState();
            states.push(make_pair(s, e));
            graph[s].push_back(make_pair(e, c));
            continue;
        }
        switch (c)
        {
        case '*': {
            pair<int, int> origin = states.top(); states.pop();
            s = newState();
            e = newState();
            states.push(make_pair(s, e));
            graph[s].push_back(make_pair(origin.first, ' '));
            graph[s].push_back(make_pair(e, ' '));
            graph[origin.second].push_back(make_pair(e, ' '));
            graph[origin.second].push_back(make_pair(origin.first, ' '));
            break;
        }
        case '.': {
            pair<int, int> right = states.top(); states.pop();
            pair<int, int> left = states.top(); states.pop();
            states.push(make_pair(left.first, right.second));
            graph[left.second].push_back(make_pair(right.first, ' '));
            break;
        }
        case '|': {
            pair<int, int> down = states.top(); states.pop();
            pair<int, int> up = states.top(); states.pop();
            s = newState();
            e = newState();
            states.push(make_pair(s, e));
            graph[s].push_back(make_pair(up.first, ' '));
            graph[s].push_back(make_pair(down.first, ' '));
            graph[up.second].push_back(make_pair(e, ' '));
            graph[down.second].push_back(make_pair(e, ' '));
            break;
        }
        default:
            break;
        }
    }
    se = make_pair(states.top().first, states.top().second);
}
// 输出NFA
void NFA::printNFA(ofstream& fout) {
    fout << "name: " << name << "\n"
        << "re: " << re << "\n"
        << "pe: " << pe << "\n"
        << "stateNum: " << stateNum << "\n"
        << "start: " << se.first << "\n"
        << "end: " << se.second << endl;
    for(int i = 1; i <= stateNum; i++) {
        for(auto edge : graph[i]) {
            fout << i << "----" << edge.second << "---->" << edge.first << "\n";
        }
    }
    fout << endl;
}

int main(void)
{
    ifstream fin("re.txt");
    ofstream fout("NFA.txt");   // 指定输出文件
    string name, re;
    while(fin >> name >> re) {
        NFA nfa(name, re);
        nfa.insertContact();
        nfa.re2Pe();
        nfa.pe2NFA();
        nfa.printNFA(fout);
    }
    return 0;
}

在这里插入图片描述
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-04 19:21:28  更:2021-07-04 19:21:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 3:17:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码