前缀、中缀、后缀表达式相互转换工具

2024-03-23 23:59

本文主要是介绍前缀、中缀、后缀表达式相互转换工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1. 界面一览

2. 使用说明

3. 实例演示

3.1 输入中缀

3.2 输入前缀

3.3 输入后缀

3.4 选择错误的类型

4. 代码

5. 资源地址


关于什么是前缀、中缀、后缀表达式,相信你不知道这个东西,那你也不会点进来这篇博客,当然,我刚刚也有写一个简单的介绍(前缀、中缀、后缀表达式介绍)。

1. 界面一览


2. 使用说明

你需要选择你输入的值是什么表达式类型,本来我是想要写一个自动检测输入的表达式是属于哪一种,但是奈何能力有限,搞了大半天都没搞出来,立即推,果断放弃,转换思路,让你自己选,总不能你自己都不知道你输的是啥吧哈哈哈。

在你输入得到时候,如果输入空格和中文的圆括号,后台会自动操作,不必担心,这也是为了方便自己,懒得输入法来回切换了,果然,懒惰是人类进步的动力。

上面黄色背景的是简单的举例,不用你自己再去算了,至于计算的功能,我没写,这个玩意随便一个 IDE 都能实现。

点击开始转换就会进行转换,根据你的选择的不同,会显示不同的结果,具体请看下面的实例演示。

输入值之后直接回车,也会触发转换,省去点击按钮的时间。

清空和关闭想必不用我多说了吧。

隐藏功能:这个功能会记住及上次移动的位置,不会每次都出现在固定的位置,方便每个人的操作。


3. 实例演示

3.1 输入中缀


3.2 输入前缀


3.3 输入后缀


3.4 选择错误的类型


4. 代码

using System;
using System.Collections.Generic;
using System.Windows.Forms;namespace TypeConversion
{public partial class frmChangeType : Form{public frmChangeType(){InitializeComponent();}/// <summary>/// 清空/// </summary>private void btnClear_Click(object sender, EventArgs e){txtInPut.Text = "";txtA2B.Text = "";lblA2B.Text = "待转换:";txtA2C.Text = "";lblA2C.Text = "待转换:";}/// <summary>/// 窗体加载/// </summary>private void Form1_Load(object sender, EventArgs e){cboType.Items.Add("前缀");cboType.Items.Add("中缀");cboType.Items.Add("后缀");cboType.SelectedIndex = 1;btnClear_Click(sender, e);txtInPut.KeyPress += txtInPut_KeyPress;// 将文本框的 KeyPress 事件与事件处理程序关联// 从应用程序设置中加载窗体位置if (Properties.Settings.Default.WindowLocation != null){this.Location = Properties.Settings.Default.WindowLocation;}}/// <summary>/// 窗体关闭自动保存上次窗体所在的位置/// </summary>protected override void OnFormClosing(FormClosingEventArgs e){base.OnFormClosing(e);// 保存窗体位置到应用程序设置Properties.Settings.Default.WindowLocation = this.Location;Properties.Settings.Default.Save();}/// <summary>/// 输入文本回车触发事件/// </summary>private void txtInPut_KeyPress(object sender, KeyPressEventArgs e){// 判断按下的键是否是回车键if (e.KeyChar == (char)Keys.Enter){btnChange_Click(sender, e);}}/// <summary>/// 转换按钮/// </summary>private void btnChange_Click(object sender, EventArgs e){// 获取当前选中的值string selectedValue = cboType.SelectedItem.ToString();// 记录返回结果string result;// 去除所有空格string sInPut = txtInPut.Text.Replace(" ", "");// 替换中文括号为英文括号sInPut = sInPut.Replace("(", "(").Replace(")", ")");if (sInPut == ""){MessageBox.Show("请输入值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);return;}ChangeMethods chmth = new ChangeMethods();try{if (selectedValue == "前缀"){result = chmth.ConvertPrefixToInfix(sInPut);lblA2B.Text = "前转中:";txtA2B.Text = result;result = chmth.ConvertPrefixToPostfix(sInPut);lblA2C.Text = "前转后:";txtA2C.Text = result;}else if (selectedValue == "中缀"){result = chmth.ConvertInfixToPrefix(sInPut);lblA2B.Text = "中转前:";txtA2B.Text = result;result = chmth.ConvertInfixToPostfix(sInPut);lblA2C.Text = "中转后:";txtA2C.Text = result;}else if (selectedValue == "后缀"){result = chmth.ConvertPostfixToPrefix(sInPut);lblA2B.Text = "后转前:";txtA2B.Text = result;result = chmth.ConvertPostfixToInfix(sInPut);lblA2C.Text = "后转中:";txtA2C.Text = result;}}catch (Exception ex){MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Information);}}/// <summary>/// 关闭按钮/// </summary>private void btnClose_Click(object sender, EventArgs e){Close();}}
}/// <summary>
/// 转换的具体方法
/// </summary>
public class ChangeMethods
{public bool IsOperand(char c){return Char.IsLetterOrDigit(c);}/// <summary>/// 判定操作数/// </summary>public bool IsOperator(char c){return c == '+' || c == '-' || c == '*' || c == '/';}/// <summary>/// 前转中/// </summary>public string ConvertPrefixToInfix(string sInPut){Stack<string> stack = new Stack<string>();try{// 从右到左遍历前缀表达式for (int i = sInPut.Length - 1; i >= 0; i--){char c = sInPut[i];if (IsOperator(c)){// 弹出两个操作数string operand1 = stack.Pop();string operand2 = stack.Pop();// 构建中缀表达式string infix = "(" + operand1 + c + operand2 + ")";// 将中缀表达式入栈stack.Push(infix);}else{// 将操作数入栈stack.Push(c.ToString());}}// 栈顶元素即为转换后的中缀表达式return stack.Pop();}catch (Exception ex){throw new Exception("前缀表达式转中缀表达式时发生异常: " + ex.Message);}}/// <summary>/// 前转后/// </summary>public string ConvertPrefixToPostfix(string sInPut){Stack<string> stack = new Stack<string>();try{// 从右到左遍历前缀表达式for (int i = sInPut.Length - 1; i >= 0; i--){char c = sInPut[i];if (IsOperator(c)){// 弹出两个操作数string operand1 = stack.Pop();string operand2 = stack.Pop();// 构建后缀表达式string postfix = operand1 + operand2 + c;// 将后缀表达式入栈stack.Push(postfix);}else{// 将操作数入栈stack.Push(c.ToString());}}// 栈顶元素即为转换后的后缀表达式return stack.Pop();}catch (Exception ex){throw new Exception("前缀表达式转后缀表达式时发生异常: " + ex.Message);}}/// <summary>/// 中转前/// </summary>public string ConvertInfixToPrefix(string infixExpression){Stack<char> operatorStack = new Stack<char>();Stack<string> operandStack = new Stack<string>();try{// 遍历中缀表达式for (int i = 0; i < infixExpression.Length; i++){char c = infixExpression[i];if (c == ' '){continue;}else if (Char.IsLetterOrDigit(c)){// 操作数直接入栈operandStack.Push(c.ToString());}else if (c == '('){// 左括号直接入栈operatorStack.Push(c);}else if (c == ')'){// 右括号,弹出操作符和操作数,构建前缀表达式while (operatorStack.Count > 0 && operatorStack.Peek() != '('){char op = operatorStack.Pop();string operand2 = operandStack.Pop();string operand1 = operandStack.Pop();string prefix = op + operand1 + operand2;operandStack.Push(prefix);}// 弹出左括号operatorStack.Pop();}else{// 操作符,根据优先级处理while (operatorStack.Count > 0 && operatorStack.Peek() != '(' && GetOperatorPriority(c) <= GetOperatorPriority(operatorStack.Peek())){char op = operatorStack.Pop();string operand2 = operandStack.Pop();string operand1 = operandStack.Pop();string prefix = op + operand1 + operand2;operandStack.Push(prefix);}// 当前操作符入栈operatorStack.Push(c);}}// 处理剩余的操作符和操作数while (operatorStack.Count > 0){char op = operatorStack.Pop();string operand2 = operandStack.Pop();string operand1 = operandStack.Pop();string prefix = op + operand1 + operand2;operandStack.Push(prefix);}// 栈顶元素即为转换后的前缀表达式return operandStack.Pop();}catch (Exception ex){throw new Exception("中缀表达式转前缀表达式时发生异常: " + ex.Message);}}/// <summary>/// 中转后/// </summary>public string ConvertInfixToPostfix(string infixExpression){Stack<char> operatorStack = new Stack<char>();List<string> postfixList = new List<string>();try{// 遍历中缀表达式for (int i = 0; i < infixExpression.Length; i++){char c = infixExpression[i];if (c == ' '){continue;}else if (Char.IsLetterOrDigit(c)){// 操作数直接加入后缀表达式列表postfixList.Add(c.ToString());}else if (c == '('){// 左括号直接入栈operatorStack.Push(c);}else if (c == ')'){// 右括号,弹出操作符,将操作符加入后缀表达式列表while (operatorStack.Count > 0 && operatorStack.Peek() != '('){postfixList.Add(operatorStack.Pop().ToString());}// 弹出左括号operatorStack.Pop();}else{// 操作符,根据优先级处理while (operatorStack.Count > 0 && operatorStack.Peek() != '(' && GetOperatorPriority(c) <= GetOperatorPriority(operatorStack.Peek())){postfixList.Add(operatorStack.Pop().ToString());}// 当前操作符入栈operatorStack.Push(c);}}// 将剩余的操作符加入后缀表达式列表while (operatorStack.Count > 0){postfixList.Add(operatorStack.Pop().ToString());}// 将后缀表达式列表转换为字符串string postfixExpression = string.Join("", postfixList);return postfixExpression;}catch (Exception ex){throw new Exception("中缀表达式转后缀表达式时发生异常: " + ex.Message);}}/// <summary>/// 后转前/// </summary>public string ConvertPostfixToPrefix(string postfixExpression){Stack<string> stack = new Stack<string>();try{// 遍历后缀表达式for (int i = 0; i < postfixExpression.Length; i++){char c = postfixExpression[i];if (IsOperator(c)){// 弹出两个操作数string operand2 = stack.Pop();string operand1 = stack.Pop();// 构建前缀表达式string prefix = c + operand1 + operand2;// 将前缀表达式入栈stack.Push(prefix);}else{// 将操作数入栈stack.Push(c.ToString());}}// 栈顶元素即为转换后的前缀表达式return stack.Pop();}catch (Exception ex){throw new Exception("后缀表达式转前缀表达式时发生异常: " + ex.Message);}}/// <summary>/// 后转中/// </summary>public string ConvertPostfixToInfix(string postfixExpression){Stack<string> stack = new Stack<string>();try{// 遍历后缀表达式for (int i = 0; i < postfixExpression.Length; i++){char c = postfixExpression[i];if (IsOperator(c)){// 弹出两个操作数string operand2 = stack.Pop();string operand1 = stack.Pop();// 构建中缀表达式string infix = "(" + operand1 + c + operand2 + ")";// 将中缀表达式入栈stack.Push(infix);}else{// 将操作数入栈stack.Push(c.ToString());}}// 栈顶元素即为转换后的中缀表达式return stack.Pop();}catch (Exception ex){throw new Exception("后缀表达式转中缀表达式时发生异常: " + ex.Message);}}/// <summary>/// 获取操作数优先级/// </summary>public int GetOperatorPriority(char op){switch (op){case '+':case '-':return 1;case '*':case '/':return 2;default:return 0;}}
}

5. 资源地址

代码

这篇关于前缀、中缀、后缀表达式相互转换工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/839924

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

超强的截图工具:PixPin

你是否还在为寻找一款功能强大、操作简便的截图工具而烦恼?市面上那么多工具,常常让人无从选择。今天,想给大家安利一款神器——PixPin,一款真正解放双手的截图工具。 想象一下,你只需要按下快捷键就能轻松完成多种截图任务,还能快速编辑、标注甚至保存多种格式的图片。这款工具能满足这些需求吗? PixPin不仅支持全屏、窗口、区域截图等基础功能,它还可以进行延时截图,让你捕捉到每个关键画面。不仅如此

PDF 软件如何帮助您编辑、转换和保护文件。

如何找到最好的 PDF 编辑器。 无论您是在为您的企业寻找更高效的 PDF 解决方案,还是尝试组织和编辑主文档,PDF 编辑器都可以在一个地方提供您需要的所有工具。市面上有很多 PDF 编辑器 — 在决定哪个最适合您时,请考虑这些因素。 1. 确定您的 PDF 文档软件需求。 不同的 PDF 文档软件程序可以具有不同的功能,因此在决定哪个是最适合您的 PDF 软件之前,请花点时间评估您的

PR曲线——一个更敏感的性能评估工具

在不均衡数据集的情况下,精确率-召回率(Precision-Recall, PR)曲线是一种非常有用的工具,因为它提供了比传统的ROC曲线更准确的性能评估。以下是PR曲线在不均衡数据情况下的一些作用: 关注少数类:在不均衡数据集中,少数类的样本数量远少于多数类。PR曲线通过关注少数类(通常是正类)的性能来弥补这一点,因为它直接评估模型在识别正类方面的能力。 精确率与召回率的平衡:精确率(Pr

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

10个好用的AI写作工具【亲测免费】

1. 光速写作 传送入口:http://u3v.cn/6hXWYa AI打工神器,一键生成文章&ppt 2. 讯飞写作 传送入口:http://m6z.cn/5ODiSw 3. 讯飞绘文 传送入口:https://turbodesk.xfyun.cn/?channelid=gj3 4. AI排版助手 传送入口:http://m6z.cn/6ppnPn 5. Kim