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


    目录

    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. 代码

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Windows.Forms;
    4. namespace TypeConversion
    5. {
    6. public partial class frmChangeType : Form
    7. {
    8. public frmChangeType()
    9. {
    10. InitializeComponent();
    11. }
    12. ///
    13. /// 清空
    14. ///
    15. private void btnClear_Click(object sender, EventArgs e)
    16. {
    17. txtInPut.Text = "";
    18. txtA2B.Text = "";
    19. lblA2B.Text = "待转换:";
    20. txtA2C.Text = "";
    21. lblA2C.Text = "待转换:";
    22. }
    23. ///
    24. /// 窗体加载
    25. ///
    26. private void Form1_Load(object sender, EventArgs e)
    27. {
    28. cboType.Items.Add("前缀");
    29. cboType.Items.Add("中缀");
    30. cboType.Items.Add("后缀");
    31. cboType.SelectedIndex = 1;
    32. btnClear_Click(sender, e);
    33. txtInPut.KeyPress += txtInPut_KeyPress;// 将文本框的 KeyPress 事件与事件处理程序关联
    34. // 从应用程序设置中加载窗体位置
    35. if (Properties.Settings.Default.WindowLocation != null)
    36. {
    37. this.Location = Properties.Settings.Default.WindowLocation;
    38. }
    39. }
    40. ///
    41. /// 窗体关闭自动保存上次窗体所在的位置
    42. ///
    43. protected override void OnFormClosing(FormClosingEventArgs e)
    44. {
    45. base.OnFormClosing(e);
    46. // 保存窗体位置到应用程序设置
    47. Properties.Settings.Default.WindowLocation = this.Location;
    48. Properties.Settings.Default.Save();
    49. }
    50. ///
    51. /// 输入文本回车触发事件
    52. ///
    53. private void txtInPut_KeyPress(object sender, KeyPressEventArgs e)
    54. {
    55. // 判断按下的键是否是回车键
    56. if (e.KeyChar == (char)Keys.Enter)
    57. {
    58. btnChange_Click(sender, e);
    59. }
    60. }
    61. ///
    62. /// 转换按钮
    63. ///
    64. private void btnChange_Click(object sender, EventArgs e)
    65. {
    66. // 获取当前选中的值
    67. string selectedValue = cboType.SelectedItem.ToString();
    68. // 记录返回结果
    69. string result;
    70. // 去除所有空格
    71. string sInPut = txtInPut.Text.Replace(" ", "");
    72. // 替换中文括号为英文括号
    73. sInPut = sInPut.Replace("(", "(").Replace(")", ")");
    74. if (sInPut == "")
    75. {
    76. MessageBox.Show("请输入值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
    77. return;
    78. }
    79. ChangeMethods chmth = new ChangeMethods();
    80. try
    81. {
    82. if (selectedValue == "前缀")
    83. {
    84. result = chmth.ConvertPrefixToInfix(sInPut);
    85. lblA2B.Text = "前转中:";
    86. txtA2B.Text = result;
    87. result = chmth.ConvertPrefixToPostfix(sInPut);
    88. lblA2C.Text = "前转后:";
    89. txtA2C.Text = result;
    90. }
    91. else if (selectedValue == "中缀")
    92. {
    93. result = chmth.ConvertInfixToPrefix(sInPut);
    94. lblA2B.Text = "中转前:";
    95. txtA2B.Text = result;
    96. result = chmth.ConvertInfixToPostfix(sInPut);
    97. lblA2C.Text = "中转后:";
    98. txtA2C.Text = result;
    99. }
    100. else if (selectedValue == "后缀")
    101. {
    102. result = chmth.ConvertPostfixToPrefix(sInPut);
    103. lblA2B.Text = "后转前:";
    104. txtA2B.Text = result;
    105. result = chmth.ConvertPostfixToInfix(sInPut);
    106. lblA2C.Text = "后转中:";
    107. txtA2C.Text = result;
    108. }
    109. }
    110. catch (Exception ex)
    111. {
    112. MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Information);
    113. }
    114. }
    115. ///
    116. /// 关闭按钮
    117. ///
    118. private void btnClose_Click(object sender, EventArgs e)
    119. {
    120. Close();
    121. }
    122. }
    123. }
    124. ///
    125. /// 转换的具体方法
    126. ///
    127. public class ChangeMethods
    128. {
    129. public bool IsOperand(char c)
    130. {
    131. return Char.IsLetterOrDigit(c);
    132. }
    133. ///
    134. /// 判定操作数
    135. ///
    136. public bool IsOperator(char c)
    137. {
    138. return c == '+' || c == '-' || c == '*' || c == '/';
    139. }
    140. ///
    141. /// 前转中
    142. ///
    143. public string ConvertPrefixToInfix(string sInPut)
    144. {
    145. Stack<string> stack = new Stack<string>();
    146. try
    147. {
    148. // 从右到左遍历前缀表达式
    149. for (int i = sInPut.Length - 1; i >= 0; i--)
    150. {
    151. char c = sInPut[i];
    152. if (IsOperator(c))
    153. {
    154. // 弹出两个操作数
    155. string operand1 = stack.Pop();
    156. string operand2 = stack.Pop();
    157. // 构建中缀表达式
    158. string infix = "(" + operand1 + c + operand2 + ")";
    159. // 将中缀表达式入栈
    160. stack.Push(infix);
    161. }
    162. else
    163. {
    164. // 将操作数入栈
    165. stack.Push(c.ToString());
    166. }
    167. }
    168. // 栈顶元素即为转换后的中缀表达式
    169. return stack.Pop();
    170. }
    171. catch (Exception ex)
    172. {
    173. throw new Exception("前缀表达式转中缀表达式时发生异常: " + ex.Message);
    174. }
    175. }
    176. ///
    177. /// 前转后
    178. ///
    179. public string ConvertPrefixToPostfix(string sInPut)
    180. {
    181. Stack<string> stack = new Stack<string>();
    182. try
    183. {
    184. // 从右到左遍历前缀表达式
    185. for (int i = sInPut.Length - 1; i >= 0; i--)
    186. {
    187. char c = sInPut[i];
    188. if (IsOperator(c))
    189. {
    190. // 弹出两个操作数
    191. string operand1 = stack.Pop();
    192. string operand2 = stack.Pop();
    193. // 构建后缀表达式
    194. string postfix = operand1 + operand2 + c;
    195. // 将后缀表达式入栈
    196. stack.Push(postfix);
    197. }
    198. else
    199. {
    200. // 将操作数入栈
    201. stack.Push(c.ToString());
    202. }
    203. }
    204. // 栈顶元素即为转换后的后缀表达式
    205. return stack.Pop();
    206. }
    207. catch (Exception ex)
    208. {
    209. throw new Exception("前缀表达式转后缀表达式时发生异常: " + ex.Message);
    210. }
    211. }
    212. ///
    213. /// 中转前
    214. ///
    215. public string ConvertInfixToPrefix(string infixExpression)
    216. {
    217. Stack<char> operatorStack = new Stack<char>();
    218. Stack<string> operandStack = new Stack<string>();
    219. try
    220. {
    221. // 遍历中缀表达式
    222. for (int i = 0; i < infixExpression.Length; i++)
    223. {
    224. char c = infixExpression[i];
    225. if (c == ' ')
    226. {
    227. continue;
    228. }
    229. else if (Char.IsLetterOrDigit(c))
    230. {
    231. // 操作数直接入栈
    232. operandStack.Push(c.ToString());
    233. }
    234. else if (c == '(')
    235. {
    236. // 左括号直接入栈
    237. operatorStack.Push(c);
    238. }
    239. else if (c == ')')
    240. {
    241. // 右括号,弹出操作符和操作数,构建前缀表达式
    242. while (operatorStack.Count > 0 && operatorStack.Peek() != '(')
    243. {
    244. char op = operatorStack.Pop();
    245. string operand2 = operandStack.Pop();
    246. string operand1 = operandStack.Pop();
    247. string prefix = op + operand1 + operand2;
    248. operandStack.Push(prefix);
    249. }
    250. // 弹出左括号
    251. operatorStack.Pop();
    252. }
    253. else
    254. {
    255. // 操作符,根据优先级处理
    256. while (operatorStack.Count > 0 && operatorStack.Peek() != '(' && GetOperatorPriority(c) <= GetOperatorPriority(operatorStack.Peek()))
    257. {
    258. char op = operatorStack.Pop();
    259. string operand2 = operandStack.Pop();
    260. string operand1 = operandStack.Pop();
    261. string prefix = op + operand1 + operand2;
    262. operandStack.Push(prefix);
    263. }
    264. // 当前操作符入栈
    265. operatorStack.Push(c);
    266. }
    267. }
    268. // 处理剩余的操作符和操作数
    269. while (operatorStack.Count > 0)
    270. {
    271. char op = operatorStack.Pop();
    272. string operand2 = operandStack.Pop();
    273. string operand1 = operandStack.Pop();
    274. string prefix = op + operand1 + operand2;
    275. operandStack.Push(prefix);
    276. }
    277. // 栈顶元素即为转换后的前缀表达式
    278. return operandStack.Pop();
    279. }
    280. catch (Exception ex)
    281. {
    282. throw new Exception("中缀表达式转前缀表达式时发生异常: " + ex.Message);
    283. }
    284. }
    285. ///
    286. /// 中转后
    287. ///
    288. public string ConvertInfixToPostfix(string infixExpression)
    289. {
    290. Stack<char> operatorStack = new Stack<char>();
    291. List<string> postfixList = new List<string>();
    292. try
    293. {
    294. // 遍历中缀表达式
    295. for (int i = 0; i < infixExpression.Length; i++)
    296. {
    297. char c = infixExpression[i];
    298. if (c == ' ')
    299. {
    300. continue;
    301. }
    302. else if (Char.IsLetterOrDigit(c))
    303. {
    304. // 操作数直接加入后缀表达式列表
    305. postfixList.Add(c.ToString());
    306. }
    307. else if (c == '(')
    308. {
    309. // 左括号直接入栈
    310. operatorStack.Push(c);
    311. }
    312. else if (c == ')')
    313. {
    314. // 右括号,弹出操作符,将操作符加入后缀表达式列表
    315. while (operatorStack.Count > 0 && operatorStack.Peek() != '(')
    316. {
    317. postfixList.Add(operatorStack.Pop().ToString());
    318. }
    319. // 弹出左括号
    320. operatorStack.Pop();
    321. }
    322. else
    323. {
    324. // 操作符,根据优先级处理
    325. while (operatorStack.Count > 0 && operatorStack.Peek() != '(' && GetOperatorPriority(c) <= GetOperatorPriority(operatorStack.Peek()))
    326. {
    327. postfixList.Add(operatorStack.Pop().ToString());
    328. }
    329. // 当前操作符入栈
    330. operatorStack.Push(c);
    331. }
    332. }
    333. // 将剩余的操作符加入后缀表达式列表
    334. while (operatorStack.Count > 0)
    335. {
    336. postfixList.Add(operatorStack.Pop().ToString());
    337. }
    338. // 将后缀表达式列表转换为字符串
    339. string postfixExpression = string.Join("", postfixList);
    340. return postfixExpression;
    341. }
    342. catch (Exception ex)
    343. {
    344. throw new Exception("中缀表达式转后缀表达式时发生异常: " + ex.Message);
    345. }
    346. }
    347. ///
    348. /// 后转前
    349. ///
    350. public string ConvertPostfixToPrefix(string postfixExpression)
    351. {
    352. Stack<string> stack = new Stack<string>();
    353. try
    354. {
    355. // 遍历后缀表达式
    356. for (int i = 0; i < postfixExpression.Length; i++)
    357. {
    358. char c = postfixExpression[i];
    359. if (IsOperator(c))
    360. {
    361. // 弹出两个操作数
    362. string operand2 = stack.Pop();
    363. string operand1 = stack.Pop();
    364. // 构建前缀表达式
    365. string prefix = c + operand1 + operand2;
    366. // 将前缀表达式入栈
    367. stack.Push(prefix);
    368. }
    369. else
    370. {
    371. // 将操作数入栈
    372. stack.Push(c.ToString());
    373. }
    374. }
    375. // 栈顶元素即为转换后的前缀表达式
    376. return stack.Pop();
    377. }
    378. catch (Exception ex)
    379. {
    380. throw new Exception("后缀表达式转前缀表达式时发生异常: " + ex.Message);
    381. }
    382. }
    383. ///
    384. /// 后转中
    385. ///
    386. public string ConvertPostfixToInfix(string postfixExpression)
    387. {
    388. Stack<string> stack = new Stack<string>();
    389. try
    390. {
    391. // 遍历后缀表达式
    392. for (int i = 0; i < postfixExpression.Length; i++)
    393. {
    394. char c = postfixExpression[i];
    395. if (IsOperator(c))
    396. {
    397. // 弹出两个操作数
    398. string operand2 = stack.Pop();
    399. string operand1 = stack.Pop();
    400. // 构建中缀表达式
    401. string infix = "(" + operand1 + c + operand2 + ")";
    402. // 将中缀表达式入栈
    403. stack.Push(infix);
    404. }
    405. else
    406. {
    407. // 将操作数入栈
    408. stack.Push(c.ToString());
    409. }
    410. }
    411. // 栈顶元素即为转换后的中缀表达式
    412. return stack.Pop();
    413. }
    414. catch (Exception ex)
    415. {
    416. throw new Exception("后缀表达式转中缀表达式时发生异常: " + ex.Message);
    417. }
    418. }
    419. ///
    420. /// 获取操作数优先级
    421. ///
    422. public int GetOperatorPriority(char op)
    423. {
    424. switch (op)
    425. {
    426. case '+':
    427. case '-':
    428. return 1;
    429. case '*':
    430. case '/':
    431. return 2;
    432. default:
    433. return 0;
    434. }
    435. }
    436. }

    5. 资源地址

    代码

  • 相关阅读:
    【无标题】
    std::call_once
    高级架构师_Redis_第4章Redis 发布与订阅+事务+lua脚本+ 慢查询日志+监视器
    three.js(二):webpack + three.js + ts
    MySQL 备份和恢复
    UE4 粒子特效基础学习 (04-光圈效果制作)
    9-Spring架构源码分析-IoC 之解析 bean 标签:开启解析进程
    BUSMASTER使用记录(二):诊断功能、在线16进制转字符串、脚本编写
    深入剖析HTTP和HTTPS代理在爬虫中的应用价值
    SOHO帮客户找新品,如何拿到最优价?要不要选择大型机械类产品?
  • 原文地址:https://blog.csdn.net/qq_57163366/article/details/133377528