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

你需要选择你输入的值是什么表达式类型,本来我是想要写一个自动检测输入的表达式是属于哪一种,但是奈何能力有限,搞了大半天都没搞出来,立即推,果断放弃,转换思路,让你自己选,总不能你自己都不知道你输的是啥吧哈哈哈。
在你输入得到时候,如果输入空格和中文的圆括号,后台会自动操作,不必担心,这也是为了方便自己,懒得输入法来回切换了,果然,懒惰是人类进步的动力。
上面黄色背景的是简单的举例,不用你自己再去算了,至于计算的功能,我没写,这个玩意随便一个 IDE 都能实现。
点击开始转换就会进行转换,根据你的选择的不同,会显示不同的结果,具体请看下面的实例演示。
输入值之后直接回车,也会触发转换,省去点击按钮的时间。
清空和关闭想必不用我多说了吧。
隐藏功能:这个功能会记住及上次移动的位置,不会每次都出现在固定的位置,方便每个人的操作。




- using System;
- using System.Collections.Generic;
- using System.Windows.Forms;
-
- namespace TypeConversion
- {
- public partial class frmChangeType : Form
- {
- public frmChangeType()
- {
- InitializeComponent();
- }
-
- ///
- /// 清空
- ///
- private void btnClear_Click(object sender, EventArgs e)
- {
- txtInPut.Text = "";
- txtA2B.Text = "";
- lblA2B.Text = "待转换:";
- txtA2C.Text = "";
- lblA2C.Text = "待转换:";
- }
-
- ///
- /// 窗体加载
- ///
- 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;
- }
- }
-
- ///
- /// 窗体关闭自动保存上次窗体所在的位置
- ///
- protected override void OnFormClosing(FormClosingEventArgs e)
- {
- base.OnFormClosing(e);
-
- // 保存窗体位置到应用程序设置
- Properties.Settings.Default.WindowLocation = this.Location;
- Properties.Settings.Default.Save();
- }
-
- ///
- /// 输入文本回车触发事件
- ///
- private void txtInPut_KeyPress(object sender, KeyPressEventArgs e)
- {
- // 判断按下的键是否是回车键
- if (e.KeyChar == (char)Keys.Enter)
- {
- btnChange_Click(sender, e);
- }
- }
-
- ///
- /// 转换按钮
- ///
- 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);
- }
- }
-
- ///
- /// 关闭按钮
- ///
- private void btnClose_Click(object sender, EventArgs e)
- {
- Close();
- }
- }
- }
-
- ///
- /// 转换的具体方法
- ///
- public class ChangeMethods
- {
- public bool IsOperand(char c)
- {
- return Char.IsLetterOrDigit(c);
- }
-
- ///
- /// 判定操作数
- ///
- public bool IsOperator(char c)
- {
- return c == '+' || c == '-' || c == '*' || c == '/';
- }
-
- ///
- /// 前转中
- ///
- 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);
- }
- }
-
- ///
- /// 前转后
- ///
- 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);
- }
- }
-
- ///
- /// 中转前
- ///
- 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);
- }
- }
-
- ///
- /// 中转后
- ///
- 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);
- }
- }
-
- ///
- /// 后转前
- ///
- 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);
- }
- }
-
- ///
- /// 后转中
- ///
- 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);
- }
- }
-
- ///
- /// 获取操作数优先级
- ///
- public int GetOperatorPriority(char op)
- {
- switch (op)
- {
- case '+':
- case '-':
- return 1;
- case '*':
- case '/':
- return 2;
- default:
- return 0;
- }
- }
- }