中缀、后缀表达式(整数)的介绍、转换及运算

  • 一.简介
  • 二.中缀表达式转后缀表达式
  • 三.中缀表达式转后缀表达式代码实现
  • 四.中缀表达式计算机求值代码实现
    • 1.首先创建一个栈类
    • 2.测试执行
  • 五.后缀表达式计算机求值代码实现

一.简介

前缀:波兰表达式(运算符在操作数之前) 如 (+ - * 3 4 5 6)
中缀:我们常见的表达式 如(3+4)* 5 – 6,便于人的理解,不利于计算机计算。
后缀:又称逆波兰表达式,如(3 4 + 5 * 6 -),便于计算机计算,但是不利于人的理解。

二.中缀表达式转后缀表达式

具体转换方式:
方式一:
1.从左到右进行遍历
2.运算数:直接输出.
3.左括号:直接压入栈(括号是最高优先级,无需比较)(入栈后优先级降到最低,确保其他符号正常入栈)
4.右括号,(意味着括号已结束)不断弹出栈顶运算符并输出,直到遇到左括号(括号弹出但不输出)
5.运算符,将该运算符与栈顶运算符进行比较,
如果优先级高于栈顶运算符,则压入栈(暂时不进行运算)。
如果优先级小于等于栈顶的运算符,则将栈顶运算符弹出并输出,然后比较新的栈顶运算符。
6.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符。

举例如下

步骤 数据 栈(栈底–>栈底) 输出
1 (3+5)*5-6
2 3+5)*5-6 (
3 +5)*5-6 ( 3
4 5)*5-6 ( + 3
5 )*5-6 ( + 3 5
6 *5-6 3 5 +
7 5-6 * 3 5 +
8 -6 * 3 5 + 5
9 6 - 3 5 + 5 *
10 - 3 5 + 5 * 6
11 3 5 + 5 * 6 -

方式二: 按照运算的顺序,每一次运算加一个括号,然后将运算符放到括号后边
注:步骤二输出结果有括号是为了表示3 5 +是一个整体,方便与后面的进行运算

步骤 数据 输出
1 (3+5)* 5 – 6
2 ((3+5))* 5 – 6 (3 5 +)* 5 – 6
3 ((3 5 +)* 5) – 6 3 5 + 5 * – 6
4 (3 5 + 5 * )– 6 3 5 + 5 * 6 -

三.中缀表达式转后缀表达式代码实现

以下有三个方法
1.change():该方法入参是一个中缀表达式-------作用是将中缀表达式转化成后缀表达式的集合

原式:(3+4)*5-6
中缀list输出结果[(, 3, +, 4, ), *, 5, -, 6]

2.compare():该方法是对运算符进行一个优先级的比较,返回1和2-----通过int类型比较比字符串比较方便。
3.out():该方法是将中缀表达式集合转化成后缀表达式集合。

中缀list输出结果[(, 3, +, 4, ), *, 5, -, 6]
后缀list输出结果[3, 4, +, 5, *, 6, -]
//将中缀表达式(字符串)转化成list   (3+4)*5-6public static List<String> change(String expression){List<String> list = new ArrayList<>();int index = 0 ;//下标char c ;//存放每一次遍历的字符String str;do {if ((c=expression.charAt(index)) < 48 || (c=expression.charAt(index)) > 57 ){//不是数字list.add(c+"");index ++;}else{//是数字str = "";//置空while (index < expression.length() && (c=expression.charAt(index)) >= 48 &&(c=expression.charAt(index)) <= 57 ){//继续往后遍历,直到遇到不是数字的str += c;index ++;}list.add(str);}}while(index < expression.length());return list;}//中缀转后缀public static List<String> out(List<String> list){Stack<String> s = new Stack<>();//存放符号List<String> l = new ArrayList<>();//存放输出的值//循环遍历listfor (String s1: list) {if (s1.matches("\\d+")){//正则匹配数字l.add(s1);}else if (s1.equals("(")){//如果是"("s.push(s1);}else if (s1.equals(")")){//如果是")"//弹出栈中的符号,放入输出的集合中,直到遇到"("while(!s.peek().equals("(")){//peek方法只是查看,但不弹出栈l.add(s.pop());}//直到遇到"(",将"("弹出栈,不加入输出的集合中s.pop();}else{//运算符while(s.size() != 0 && compare(s.peek()) >= compare(s1)){//定义一个数字表示优先级,比拿着运算符去比较方便//如果当前优先级小于或者等于栈中的运算符的优先级,就弹出,加入到输出的集合中l.add(s.pop());}s.push(s1);//将当前得运算符加入到栈中}}//清空栈,即将最后栈中的运算符加入到输出集合中while(s.size() != 0 ){l.add(s.pop());}return l;}//返回优先级的方法public static int compare(String oper){int i = 0;switch (oper){case "+":return i=1;case "-":return i=1;case "*":return i=2;case "/":return i=2;}return i;}

四.中缀表达式计算机求值代码实现

是为了模拟中缀表达式在计算机中求值的过程,例如用计算机计算(3+4)*5-6 = ?

思路:
1创建两个栈:一个数栈(存放数据),一个符号栈(存放符号)
2.通过一个index(索引),遍历表达式
3.如果发现是一个数字,就直接入数栈
4.如果是符号,分如下情况:
4.1如果当前的符号栈为空,直接入栈
4.2如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或等于栈中的操作符,就需要从数栈中pop出两个数,
再从符号栈中pop出一个符号,进行运算,将得到的结果存入数栈,然后将当前的操作符入符号栈(因为pop出,所以数栈和符号栈的栈顶都会下移,然后运算结束后添加,再将栈顶上移),如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈.
5.当表达式扫描完毕,就顺序从数栈和符号栈中pop出相应的数和符号,并运行,
6.最后在数栈的只有一个数字,就是表达式结果.

1.首先创建一个栈类

用数组模拟栈,在该类中写好基本的方法。

//定义一个ArrayStack
class Stack1{private int maxSize;//栈的大小private int[] stacks;//数组模拟栈private int top = -1;//栈顶的初始值-1public Stack1(int max){maxSize = max;stacks = new int[this.maxSize];}//栈满public boolean isFull(){return top == maxSize-1;}//栈空public boolean isNull(){return top == -1;}//入栈-pushpublic void push(int value){//先判断栈是否满if (isFull()){System.out.println("栈满");return;}top ++;stacks[top] = value;}//出栈public int pop(){if (isNull()){throw new RuntimeException("栈空");}//先保存栈顶数据int value = stacks[top];top -- ;return value;}//遍历栈public void list(){if (isNull()){System.out.println("栈空,没有数据");return;}//从栈顶遍历数据(因为先进后出)for (int i = top; i >= 0 ; i--) {System.out.println(i+ ":"+stacks[i]);}}//判断运算符的优先级(自定义比较情况),如优先级越高的返回数字越大//目前运算符只有+ - * /public int compare(int oper){if (oper == '*' || oper == '/'){return 1;} else if (oper == '+' || oper == '_'){return 0;}else {return -1;//代表运算符不正确}}//增加一个方法.返回栈顶的值,不是出栈public int pick(){return stacks[top];}//判断遍历的是不是运算符public boolean isOper(char oper){return oper == '*' || oper == '/' || oper == '+' || oper == '-';}//计算方法public int cal(int num1 , int num2 , int oper){int resault = 0;//存放计算结果switch (oper){case '+':resault = num1 + num2;break;case '-':resault = num2 - num1;//注意顺序 num2是后弹出的数break;case '*':resault = num1 * num2;break;case '/':resault = num2 + num1;break;default:break;}return resault;}

2.测试执行

{//定义一个表达式String expression = "3+20*6-2";//定义两个栈Stack1 numStack = new Stack1(10);Stack1 operStack = new Stack1(10);//定义一个索引int index = 0;//定义两个数int num1 = 0;int num2= 0;//定义运算符int oper = 0;//定义存放计算结果的数字int res = 0;char c = ' ';//保存每次扫描的char//定义一个字符串变量,保存多位数的数字String keepNum ="";//循环遍历while (true){//得到expression中的每一个字符c = expression.substring(index,index+1).charAt(0);//判断该字符是什么,然后做相应的处理if (operStack.isOper(c)){//如果是运算符//判断字符栈是否是空if (!operStack.isNull()){//不为空,执行4.2if (operStack.compare(c) <= operStack.compare(operStack.pick())){//运算级比较,当前字符和栈顶的字符num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = numStack.cal(num1,num2,oper);//把运算的结果放入数栈numStack.push(res);//把当前运算符放入运算符栈operStack.push(c);}else{//如果当前的运算符优先级大于,直接入栈operStack.push(c);}}else{//如果为空,直接入栈operStack.push(c);}}else{//不是运算符
//                numStack.push(c - 48);//如果直接保存,那么存的就是字符'1',对应的十进制是49,而不是1,所以需要减48//数据有可能是多位数的数据,如12,那么就需要判断,当前expression的下一位index是否是符号位,是的话才入数栈//因此,需要一个变量进行拼接keepNum += c;//如果已经是最后一位,则直接入栈if (index == expression.length()-1){numStack.push(Integer.parseInt(keepNum));}//判断下一位的类型else if (operStack.isOper(expression.substring(index+1,index+2).charAt(0))){//若为true,则说明下一位是运算符,则将改数据入数栈numStack.push(Integer.parseInt(keepNum));//清空keepNum!!!!!!!!!!!!!!!!!!!!!!!!!!!!keepNum = "";}}//让index + 1并判断是否扫描到最后index ++;if (index >= expression.length()){break;}}while(true){//符号栈为空,则数栈中只有一个数字(结果)if (operStack.isNull()){break;}num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = numStack.cal(num1,num2,oper);//把运算的结果放入数栈numStack.push(res);}//把数栈的最后的数,取出int ress = numStack.pop();System.out.println("表达式:" + expression + "=" + ress);}

五.后缀表达式计算机求值代码实现

是为了模拟中缀表达式在计算机中求值的过程,例如用计算机计算: (3+4)*5-6 = ? 即3 4 + 5 * 6 - = ?
直接使用系统定义的栈类,自定义一个计算方法cal(),进行测试。

public class PolandNotation {public static void main(String[] args) {//先定义一个逆波兰表达式
//        (3+4)*5-6 => 3 4 + 5 * 6 -//定义成用空格分离形式,是为了后边拆分成集合String suffixExpression = "3 4 + 5 * 6 -";List<String> list = getList(suffixExpression);int res = cal(list);System.out.println("输出结果" + res);}//将表达式分割成数组的形式,保存到list中,因为如果不存放到llist中,就需要一个index下标索引和subString方法截取,比较麻烦public static List<String> getList(String suffixExpression){//根据空格分割字符串String[] strings = suffixExpression.split(" ");List<String> list = new ArrayList<>();for (String s:strings) {list.add(s);}return list;}//    计算public static int cal(List<String> list){//创建一个栈Stack<String> stack = new Stack<>();//遍历for (String item: list) {if (item.matches("\\d+")){//正则表达式匹配//如果是数字,直接入栈stack.push(item);}else{//不是数字,说明是操作符int num1 = Integer.parseInt(stack.pop());//弹出的第一个数int num2 = Integer.parseInt(stack.pop());//弹出的第二个数int res = 0;if (item.equals("+")){res = num1 + num2;} else if (item.equals("-")){res = num2 - num1;} else if (item.equals("*")){res = num1 * num2;} else if (item.equals("/")){res = num1 / num2;}else{throw new RuntimeException("运算符有误");}//将结果放入栈,变成字符串传入stack.push(res +"");}}return Integer.parseInt(stack.pop());}
}

【中缀、后缀表达式(整数)的介绍、转换及运算】相关推荐

  1. 前缀中缀后缀表达式介绍

    一 前缀表达式 1 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前. 2 举例 (3+4)×5-6 对应的前缀表达式是: - × + 3 4 5 6 3 前缀表达式的计算机求值过程 从右至左扫 ...

  2. python【数据结构与算法】表达式(前缀中缀后缀表达式)与Two fork tree

    文章目录 1 相关概念 2 与二叉树关系 3 表达式转换 4 另一种方法 1 相关概念 前缀表达式(Prefix Notation)是指将运算符写在前面操作数写在后面的不包含括号的表达式,而且为了纪念 ...

  3. 前缀中缀后缀表达式的计算求值

    原文在这里 表达式 前缀表达式(波兰表达式) 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前 举例说明: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6 前缀表达式求值 ...

  4. 阿龙学堂-中缀-后缀表达式的计算

    1.简介 在数据结构中,有一种数据结构叫做:Stack,LIFO(Last In First Out),在这个结构中,有个后缀表达式计算,运用该数据结构进行计算. 栈是一种只允许一端操作的线性数据结构 ...

  5. 前缀 中缀 后缀表达式2

    对于未经训练的用户来说,计算机科学领域中数学表达式求值的传统方法即不顺手又难以使用:软件工程师 Nikola.Stepan 旨在改变这些传统方法.他的 applet W3Eval 对表达式求值与您用纸 ...

  6. 数据结构:前缀,中缀,后缀表达式(逆波兰表达式)

    前缀表达式(波兰表达式) 前缀表达式的运算符位于操作数之前. 比如 (1+2)*3-4  对应的前缀表达式就是: - * + 1 2 3 4 前缀表达式的计算机求值 从右至左扫描表达式,遇到数字时,就 ...

  7. 后缀表达式求值和转换(C++)

    中缀转后缀 #include<stdio.h> #include<stack> using namespace std; stack<int> s; int com ...

  8. 表达式树前缀中缀后缀表达式

    表达式树( expression tree ), 表达式树的树叶是操作数( operand ),比如常数或变量,而其他的节点为操作符( operator )如: 由于这里所有的操作都是二元的,因此这棵 ...

  9. 前缀 中缀 后缀表达式

    1.前缀表达式叫波兰式,后缀叫逆波兰式 2.中缀表达式转另外两个比较简单,前后缀装中缀较麻烦 3.问题分求表达式还是求值,如果是求值则需要两个栈,一个是操作符栈,一个是操作数栈,等操作符栈入栈完毕后依 ...

  10. (中缀)表达式转换成前缀表达式、后缀表达式

    认识前缀.中缀.后缀表达式: 一般我们平时用的计算式都是中缀表达式,因为符号都是在操作数的中间的.相对应的符号在操作数后面的就叫后缀表达式(也称逆波兰式),符号在操作数前面的就叫前缀表达式(也称波兰式 ...

最新文章

  1. Windows10 + VS2015 (Win SDK10)环境下的64位 VTK编译小结
  2. Oracle Open World 2012信息汇总贴
  3. 无限极分类,子集跟着父集排列,用于后台显示菜单管理
  4. 拼多多的真实面试题:数亿的用户,如何用Redis统计独立用户访问量
  5. LeetCode 1869. 哪种连续子字符串更长
  6. CCF NOI1017 价格查询
  7. Android 蓝牙音箱开发
  8. Docker-mysql 安装
  9. .NetCore Session.Redis (转载)
  10. 【LeetCode】【字符串】题号:*151. 翻转字符串里的单词
  11. 物联网平台发展的4个阶段和5个实践案例
  12. 企业微信群机器人php,企业微信群机器人
  13. angular烂笔头
  14. echart地图飞线图
  15. 【物联网】思科借助物联网推进工业解决方案全数字化进程
  16. 小米应用市场隐私政策
  17. c语言求成绩中的最高分辨率大约是,一级msoffice全真机试试卷.docx
  18. Python 数据分析之Numpy
  19. 40行python代码搞定王者荣耀全部壁纸下载
  20. 第 11 场双周赛-5089. 安排会议日程(双指针)

热门文章

  1. [强化学习]-网络安全资料汇总
  2. ADO_Net学习笔记---总结
  3. html标签logo图片怎么添加上去的
  4. H5监听键盘弹起收回,用法超简单!兼容Android、iOS。
  5. kaggle: quora question pairs
  6. 论文解读:Hierarchical Question-Image Co-Attention for Visual Question Answering
  7. 凸集、凸函数及其充分必要条件
  8. 测绘地图资源不够用?教你个万能图源制作方法
  9. 机器学习中的度量——相关系数
  10. python怎么升序和降序排序?