首页 > 其他分享 >11--中缀表达式转后缀表达式

11--中缀表达式转后缀表达式

时间:2022-09-06 09:12:36浏览次数:59  
标签:11 中缀 int s2 s1 ret 运算符 lists 表达式

思路步骤分析:

1、初始化两个栈,运算符栈s1和储存中间结果的栈s2

2、从左至右扫描中缀表达式

3、遇到操作数时,将其压入s2

4、遇到运算符时,比较其与s1z栈顶运算符的优先级:

4.1:如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈

4.2:否则,若优先级比栈顶运算符高,也将运算符压入s1

4.3:否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4.1)与新的栈顶运算符比较;

5、遇到括号时:

5.1:遇到左括号"(",则直接压入s1

5.2:如果是右括号")",则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃

6、重复步骤2至5,直到表达式的最右边

7、将s1中剩余的运算符依次弹出并压入s2

8、依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式

中缀表达式1+((2+3)*4)-5,图形过程:

 1 //新定义一个类【工具类】,用于比较运算符优先级
 2 class Operator{
 3     public static final int  ADD = 1;
 4     public static final int  SUB = 1;
 5     public static final int  MUL = 2;
 6     public static final int  DIV = 2;
 7     
 8     public static int priority(String item) {
 9         int ret = 0;
10         switch(item) {
11         case "+":
12             ret = ADD;
13             break;
14         case "-":
15             ret = SUB;
16             break;
17         case "*":
18             ret = MUL;
19             break;
20         case "/":
21             ret = DIV;
22             break;
23         default:
24             break;
25         }
26         return ret;
27     }
28 }
  1 import java.util.ArrayList;
  2 import java.util.List;
  3 import java.util.Stack;
  4 
  5 //逆波兰表达式的计算
  6 public class NiPolandExpression {
  7 
  8     public static void main(String[] args) {
  9         String expression = "1+((2+3)*425)-15"; //2111
 10         List<String> list = toInfixListExpression(expression);
 11         System.out.println(list);
 12         
 13         List<String> lists =  parseSuffixExpression(list);
 14         System.out.println(lists);
 15         
 16         //1、将表达式转成ArrayList集合,后遍历,每遍历一个元素将压栈
 17         Stack<String> stack = new Stack<>();
 18         for(String ele: lists) {
 19             if (ele.matches("\\d+")) { //正则表达式:表示匹配一个或者多个整数
 20                 //是数字直接入栈
 21                 stack.push(ele);
 22             }else {
 23                 //到了这里说明是符号,需要pop出2个操作数
 24                 int num2 = Integer.parseInt(stack.pop());
 25                 int num1 = Integer.parseInt(stack.pop());
 26                 int ret = 0;
 27                 switch(ele) {
 28                 case "+": 
 29                     ret = num1 + num2;
 30                     break;
 31                 case "-":
 32                     ret = num1 - num2;
 33                     break;
 34                 case "*":
 35                     ret = num1 * num2;
 36                     break;
 37                 case "/":
 38                     ret = num1 / num2;
 39                     break;
 40                     }
 41                 //将计算结果压入栈中
 42                 stack.push(ret+"");
 43             }
 44         }
 45         int result = Integer.parseInt(stack.pop());
 46         System.out.println("最终结果为:" + result);
 47     }
 48     
 49     public static List<String> getList(String expression){
 50         List<String> lists = new ArrayList<>();
 51         String[] arrays = expression.split(" ");
 52         for(String ele:arrays) {
 53             lists.add(ele);
 54         }
 55         return lists;
 56      }
 57     
 58     //将中缀表达式转成List集合
 59     public static List<String> toInfixListExpression(String expression){
 60         List<String> lists = new ArrayList<>();
 61         int i = 0; //字符串每个字符的索引
 62         char ch = ' ';
 63         while(i < expression.length()) {
 64             ch = expression.charAt(i);
 65             if (ch < '0' || ch > '9') {
 66                 //说明为运算符,直接加入到lists集合中
 67                 lists.add(ch+"");
 68                 i++;
 69             }else {
 70                 //说明改字符为数字
 71                 String str = "";
 72                 while(i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
 73                     str += expression.charAt(i++);
 74                 }
 75                 lists.add(str);
 76             }
 77         }
 78         return lists;
 79     }
 80     
 81     //中缀表达式转后缀表达式
 82     public static List<String> parseSuffixExpression(List<String> lists){
 83         //定义运算符栈
 84         Stack<String> s1 = new Stack<>();
 85         //定义存储中间结果的栈s2 【由于在转换过程中s2只添加数据,因此可以使用集合】
 86         //Stack<String> s2 = new Stack<>();
 87         List<String> s2 = new ArrayList<>();
 88         //扫描中缀表达式【集合】
 89         for(String item : lists){
 90             //如果是操作数,直接加入到s2中
 91             if (item.matches("\\d+")) {
 92                 s2.add(item);
 93             }else if ("(".equals(item)) {
 94                 //如果是左括号,直接压入s1
 95                 s1.push(item);
 96             }else if(")".equals(item)){
 97                 //依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,将这对括号丢弃
 98                 while(!"(".equals(s1.peek())) {
 99                     s2.add(s1.pop());
100                 }
101                 //弹出s1中的左括号
102                 s1.pop();
103             }else {
104                 //遇到运算符
105                 //当item的优先级小于或者等于s1栈顶的优先级时,则依次将s1栈顶的运算符pop到s2中,再次与s1新的栈顶的运算符相比较
106                 //直到当前运算符的优先级大于s1栈顶运算符的优先级
107                 //注:如果s2.peek为"("则返回0,会直接跳出循环
108                 while(s1.size() != 0 && Operator.priority(item) <= Operator.priority(s1.peek())) {
109                     s2.add(s1.pop());
110                 }
111                 //到达此处说明有3种【直接入栈s1】情况:
112                   //1、item运算符的优先级大于s1栈顶运算符的优先级
113                   //2、s1为空
114                   //3、s1栈顶为左括号
115                 s1.push(item);
116             }
117         }
118         //将s1中剩余的运算符弹出并加入到s2中
119         while(s1.size() != 0) {
120             s2.add(s1.pop());
121         }
122         return s2;
123     }
124     
125 }

标签:11,中缀,int,s2,s1,ret,运算符,lists,表达式
From: https://www.cnblogs.com/yumengqifei/p/16567764.html

相关文章

  • Windows 11恢复旧版的右键菜单
    1.打开注册表开始->运行->输入regedit->回车 2.在左边框的树,展开到以下路径:HKEY_CURRENT_USER\SOFTWARE\CLASSES\CLSID 3.右键CLSID节点,新建->项->输入{......
  • 信息学奥赛一本通 1188:菲波那契数列(2)
    时间限制:1000ms      内存限制:65536KB提交数:46311   通过数:17428【题目描述】菲波那契数列是指这样的数列:数列的第一个和第二个数都为<spa......
  • C++11~C++20 新基础类型
    目录整数类型longlong(C++11)字符类型char16_t和char32_t(C++11)C++11为什么要引入char16_t和char32_t?字符类型char8_t(C++20)参考资料整数类型longlong(C++11)C++1......
  • 1151:素数个数
    编程求2-n中有多少个素数。#include<iostream>usingnamespacestd;intmain(){   intn,s=0,sum=0;   cin>>n;   for(inti=2;i<=n;++i)   {    ......
  • 2022-2023-1 20221311《计算机基础与程序设计》第一周学习总结
    作业信息班级:https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP作业链接:https://www.cnblogs.com/rocedu/p/9577842.html#WEEK01作业目标:快速浏览教材作业正文:ht......
  • Pybind11 揭秘。 Ch 4.1:仅位置参数
    Pybind11揭秘。Ch4.1:仅位置参数Python不支持C++中的函数重载(具有相同函数名称的不同函数签名)。尽管如此,Python确实提供了一组少数语法,包括默认值和kwargs,以允许根......
  • 玩转正则表达式
    玩转正则表达式本文中介绍的是主要是 3 个知识点:正则表达式的相关知识Python的中 re 模块,主要是用来处理正则表达式一个利用 re 模块通过正则表达式来进行网页......
  • 【JS】112. 路径总和
    112.路径总和代码DFSvarhasPathSum=function(root,targetSum){//找到没有根了,那么就说明这条路行不通if(!root){returnfalse;}//......
  • 如何获取C++中变量/表达式的类型
    主要有三种方式:使用C++库自带的typeid函数;使用boost库中type_id_with_cvr函数(末尾的cvr代表const,variable,reference);自定义模板函数type_name();方式一......
  • 基于 ESP8266_RTOS_SDK 驱动 DHT11
    概述DHT11模块使用一根data线实现信号触发以及数据反馈,信号格式参考如下https://zhuanlan.zhihu.com/p/347904660本文使用GPIO中断的方式采集反馈数据知识点:GPIO、中断......