当前位置: 首页 > news >正文

基于调度场算法将中缀表达式转换为后缀表达式

中缀表达式转后缀表达式

1. 整体结构概述

这段C++代码实现了一个中缀表达式转后缀表达式(逆波兰表达式)的转换器。主要包含:

  • 一个InfixToPostfixConverter类,负责转换逻辑
  • main函数作为程序入口,进行简单测试

转换支持的运算符包括:!(阶乘)、^(幂运算)、*(乘法)、/(除法)、+(加法)、-(减法),以及括号()改变运算优先级。

2. 类成员与数据结构

私有成员

char opStack[MAXSIZE];  // 运算符栈
int opTop;              // 栈顶指针
  • 使用固定大小数组实现栈结构,MAXSIZE定义为100
  • opTop初始值为-1,表示空栈

优先级判断函数

int getOperatorPriority(char op) const {switch (op) {case '!': return 4;case '^': return 3;case '*': case '/': return 2;case '+': case '-': return 1;case '(': return 0;default: return -1;}
}

优先级从高到低为:! > ^ > *// > +/-,左括号(优先级最低。

3. 转换核心算法:convertToPostfix方法

该方法接收一个中缀表达式字符串,返回对应的后缀表达式。算法流程如下:

3.1 初始化

string postfixExpr;  // 存储结果的后缀表达式
int exprLen = infixExpr.length();  // 输入表达式长度

3.2 遍历表达式

对中缀表达式的每个字符进行处理:

3.2.1 处理左括号(

if (currentChar == '(') {if (opTop < MAXSIZE - 1) {opStack[++opTop] = currentChar;}continue;
}
  • 直接将左括号压入运算符栈

3.2.2 处理右括号)

if (currentChar == ')') {while (opTop != -1 && opStack[opTop] != '(') {postfixExpr += opStack[opTop--];  // 弹出运算符到结果}opTop--;  // 弹出左括号但不加入结果continue;
}
  • 弹出栈中所有运算符直到遇到左括号
  • 左括号只弹出不加入结果

3.2.3 处理运算符

if (currentChar是运算符) {while(opTop!=-1){char topOp=opStack[opTop];// 栈顶运算符优先级高于等于当前运算符时弹出if(getOperatorPriority(topOp)>=getOperatorPriority(currentChar)){postfixExpr+=topOp;opTop--;}else{break;}}// 当前运算符入栈if(opTop<MAXSIZE-1){opStack[++opTop]=currentChar;}continue;
}
  • 遵循"栈顶运算符优先级高于等于当前运算符则弹出"的规则
  • 最后将当前运算符压入栈

3.2.4 处理数字

if(currentChar是数字){while(i<exprLen&&infixExpr[i]是数字){postfixExpr+=infixExpr[i];  // 收集连续数字++i;}postfixExpr+='#';  // 用#标记数字结束--i;  // 调整循环变量continue;
}
  • 收集连续数字字符作为一个完整数字
  • #作为数字结束标记,方便后续计算时解析

3.3 处理剩余运算符

while(opTop!=-1){postfixExpr+=opStack[opTop--];  // 弹出所有剩余运算符
}
  • 遍历结束后,将栈中剩余运算符全部弹出到结果

4. 测试示例分析

main函数测试了表达式"2^3!"的转换:

cout<<infix.convertToPostfix("2^3!")<<endl;

转换过程分析:

  1. 读取2:数字,直接加入结果,添加#2#
  2. 读取^:运算符,栈为空,直接入栈 → 栈: ^
  3. 读取3:数字,加入结果,添加#2#3#
  4. 读取!:运算符,栈顶是^(优先级3),!优先级4更高,直接入栈 → 栈: ^, !
  5. 表达式结束,弹出所有运算符 → 2#3#!^

所以最终输出为:2#3#!^

5. 算法流程图

开始|
初始化栈和结果字符串|
遍历中缀表达式的每个字符|
├─ 若为'(' → 入栈
│
├─ 若为')' → 弹出运算符直到'(',弹出'('不加入结果
│
├─ 若为运算符 → 弹出栈中优先级>=当前运算符的运算符,当前运算符入栈
│
└─ 若为数字 → 收集连续数字,添加#标记|
遍历结束后,弹出栈中所有运算符到结果|
返回后缀表达式|
结束

该实现通过栈数据结构实现了中缀到后缀表达式的转换,核心在于运算符优先级的比较和栈操作规则。代码使用#作为数字分隔符,便于后续对后缀表达式进行计算。对于测试用例2^3!,按照运算符优先级规则,正确转换为2#3#!^
附上完整代码:

#include <iostream>
using namespace std;
const int MAXSIZE = 100;
class InfixToPostfixConverter {private:char opStack[MAXSIZE];int opTop;// 获取优先级int getOperatorPriority(char op) const {switch (op) {case '!':return 4;case '^':return 3;case '*':case '/':return 2;case '+':case '-':return 1;case '(':return 0;default:return -1;}}public:InfixToPostfixConverter() : opTop(-1) {}string convertToPostfix(const string& infixExpr) {string postfixExpr;int exprLen = infixExpr.length();for (int i = 0; i < exprLen; ++i) {char currentChar = infixExpr[i];// 左括号if (currentChar == '(') {if (opTop < MAXSIZE - 1) {opStack[++opTop] = currentChar;}continue;}// 右括号if (currentChar == ')') {while (opTop != -1 && opStack[opTop] != '(') {postfixExpr += opStack[opTop--];}// 弹出左括号opTop--;continue;}// 处理运算符if (currentChar == '+' || currentChar == '-' ||currentChar == '*' || currentChar == '/' ||currentChar == '^' || currentChar == '!') {//假定是否一直出栈while(opTop!=-1){char topOp=opStack[opTop];if(getOperatorPriority(topOp)>=getOperatorPriority(currentChar)){postfixExpr+=topOp;opTop--;}else{break;}}if(opTop<MAXSIZE-1){opStack[++opTop]=currentChar;}continue;}if(currentChar>='0'&&currentChar<='9'){while(i<exprLen&&infixExpr[i]>='0'&&infixExpr[i]<='9'){postfixExpr+=infixExpr[i];++i;}postfixExpr+='#';--i;continue;}}//所有的表达式的运算符都已经入栈后,运算符栈内仍然有剩余的运算符,弹出所有剩余的运算符while(opTop!=-1){postfixExpr+=opStack[opTop--];}return postfixExpr;}
};
int main() {InfixToPostfixConverter infix;cout<<infix.convertToPostfix("2^3!")<<endl;return 0;
}
http://www.hskmm.com/?act=detail&tid=327

相关文章:

  • 来此加密实现SSL证书自动申请+自动部署
  • lc1022-从根到叶的二进制数之和
  • 2025.9.9——1橙
  • SIM /api/function/execute 代码执行漏洞
  • C#/.NET/.NET Core技术前沿周刊 | 第 53 期(2025年9.1-9.7)
  • 3
  • linux下安装pycharm时,中文无法显示的问题
  • 学习
  • Docker,Containerd配置私有Harbor仓库和Notary服务器
  • Ubuntu安装notary
  • Ubuntu安装containerd
  • 你的错误处理一团糟-是时候修复它了-️
  • TRVCOST - Travelling cost 题解
  • 我重新制作动画系统的思路
  • 第一次作业:自我介绍+软工5问
  • 第一篇练习博客
  • 原型设计实用干货!3款热门AI生成原型图软件横向测评
  • Python Flask框架入门_3.通过token认证验证API的访问权限(数据库版本)
  • 港科 Tower A 宿舍凝水之谜
  • Transformer 模型(能理解“句子顺序”和“上下文”的神经网络架构)
  • 题解:P3546 [POI 2012] PRE-Prefixuffix
  • 自然语言处理(NLP)发展脉络
  • 错误报警:“该 CPU 或当前的库版本不支持数据类型”
  • redis各种数据类型
  • 关于 cnpm 的安装
  • 剖析“YOLO”哈希构造的安全隐患与正确替代方案
  • Charles实战秘籍:弱网模拟、Map Local/Remote、HTTPS抓包详解
  • BOE(京东方)“照亮成长路”公益项目走进富平县 科技赋能教育树立可持续发展新标杆
  • 9月23日周二《AI+企业IP获客联盟峰会》,相约东莞厚街富盈酒店
  • 第一次作业 自我介绍+软工5问