重庆最便宜的网站建设公司,网络建站详情图,企业年金个人和单位的缴费比例,天津众业建设工程有限公司网站原文在这里
表达式
前缀表达式(波兰表达式)
前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前举例说明#xff1a; (34)5-6 对应的前缀表达式就是 - 3 4 5 6
前缀表达式求值
前缀表达式的计算机求值
从右至左扫描表达式#xff0c;遇到数字时#xff0c;将数…原文在这里
表达式
前缀表达式(波兰表达式)
前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前举例说明 (34)×5-6 对应的前缀表达式就是 - × 3 4 5 6
前缀表达式求值
前缀表达式的计算机求值
从右至左扫描表达式遇到数字时将数字压入堆栈遇到运算符时弹出栈顶的两个数用运算符对它们做相应的计算栈顶元素 和 次顶元素并将结果入栈重复上述过程直到表达式最左端最后运算得出的值即为表达式的结果
例如: (34)×5-6 对应的前缀表达式就是 - × 3 4 5 6 , 针对前缀表达式求值步骤如下:
从右至左扫描将6、5、4、3压入堆栈遇到运算符因此弹出3和43为栈顶元素4为次顶元素计算出34的值得7再将7入栈接下来是×运算符因此弹出7和5计算出7×535将35入栈最后是-运算符计算出35-6的值即29由此得出最终结果
中缀表达式
中缀表达式
中缀表达式就是常见的运算表达式如(34)×5-6
中缀表达式的求值是我们人最熟悉的但是对计算机来说却不好操作(前面我们讲的案例就能看的这个问题)因此在计算结果时往往会将中缀表达式转成其它表达式来操作(一般转成后缀表达式.) 中缀表达式对于我们人来好搞,计算机他算不算明白,就离谱 计算机不知道怎么算这个优先级 后缀表达式(逆波兰表达式)
后缀表达式
后缀表达式又称逆波兰表达式,与前缀表达式相似只是运算符位于操作数之后
中举例说明 (34)×5-6 对应的后缀表达式就是 3 4 5 × 6 –
再比如:
正常的表达式逆波兰表达式aba b a(b-c)a b c - a(b-c)*da b c – d * ad*(b-c)a d b c - * a13a 1 3
后缀表达式的计算机求值
从左至右扫描表达式遇到数字时将数字压入堆栈遇到运算符时弹出栈顶的两个数用运算符对它们做相应的计算次顶元素 和 栈顶元素并将结果入栈重复上述过程直到表达式最右端最后运算得出的值即为表达式的结果
例如: (34)×5-6 对应的后缀表达式就是 3 4 5 × 6 - , 针对后缀表达式求值步骤如下:
从左至右扫描将3和4压入堆栈遇到运算符因此弹出4和34为栈顶元素3为次顶元素计算出34的值得7再将7入栈将5入栈接下来是×运算符因此弹出5和7计算出7×535将35入栈将6入栈最后是-运算符计算出35-6的值即29由此得出最终结果
我们完成一个逆波兰计算器要求完成如下任务:
输入一个逆波兰表达式(后缀表达式)使用栈(Stack), 计算其结果支持小括号和多位数整数因为这里我们主要讲的是数据结构因此计算器进行简化只支持对整数的计算。思路分析代码完成
package com.atguigu.stack;/*** ClassName: br/* Description: br/* Date: 2021-02-20 14:27 br/* project data_algorithm* package com.atguigu.stack*/import java.util.ArrayList;
import java.util.List;
import java.util.Stack;public class PolandNotation {}
//编写一个类 Operation 可以返回一个运算符 对应的优先级
class Operation {private static int ADD 1;private static int SUB 1;private static int MUL 2;private static int DIV 2;//写一个方法返回对应的优先级数字public static int getValue(String operation) {int result 0;switch (operation) {case :result ADD;break;case -:result SUB;break;case *:result MUL;break;case /:result DIV;break;default:System.out.println(不存在该运算符 operation);break;}return result;}}
//完成对逆波兰表达式的运算
/** 1)从左至右扫描将3和4压入堆栈2)遇到运算符因此弹出4和34为栈顶元素3为次顶元素计算出34的值得7再将7入栈3)将5入栈4)接下来是×运算符因此弹出5和7计算出7×535将35入栈5)将6入栈6)最后是-运算符计算出35-6的值即29由此得出最终结果*/public static int calculate(ListString ls) {// 创建给栈, 只需要一个栈即可StackString stack new StackString();// 遍历 lsfor (String item : ls) {// 这里使用正则表达式来取出数if (item.matches(\\d)) { // 匹配的是多位数// 入栈stack.push(item);} else {// pop出两个数并运算 再入栈int num2 Integer.parseInt(stack.pop());int num1 Integer.parseInt(stack.pop());int res 0;if (item.equals()) {res num1 num2;} else if (item.equals(-)) {res num1 - num2;} else if (item.equals(*)) {res num1 * num2;} else if (item.equals(/)) {res num1 / num2;} else {throw new RuntimeException(运算符有误);}//把res 入栈stack.push( res);}}//最后留在stack中的数据是运算结果return Integer.parseInt(stack.pop());
}
//将一个逆波兰表达式 依次将数据和运算符 放入到 ArrayList中
public static ListString getListString(String suffixExpression) {//将 suffixExpression 分割String[] split suffixExpression.split( );ListString list new ArrayListString();for(String ele: split) {list.add(ele);}return list;}
//方法将 中缀表达式转成对应的List
// s1((23)×4)-5;
public static ListString toInfixExpressionList(String s) {//定义一个List,存放中缀表达式 对应的内容ListString ls new ArrayListString();int i 0; //这时是一个指针用于遍历 中缀表达式字符串String str; // 对多位数的拼接char c; // 每遍历到一个字符就放入到cdo {//如果c是一个非数字我需要加入到lsif((cs.charAt(i)) 48 || (cs.charAt(i)) 57) {ls.add( c);i; //i需要后移} else { //如果是一个数需要考虑多位数str ; //先将str 置成 0[48]-9[57]while(i s.length() (cs.charAt(i)) 48 (cs.charAt(i)) 57) {str c;//拼接i;}ls.add(str);}}while(i s.length());return ls;//返回
}
//即 ArrayList [1,,(,(,2,,3,),*,4,),-,5] 》 ArrayList [1,2,3,,4,*,,5,–]
//方法将得到的中缀表达式对应的List 后缀表达式对应的List
public static ListString parseSuffixExpreesionList(ListString ls) {//定义两个栈StackString s1 new StackString(); // 符号栈//说明因为s2 这个栈在整个转换过程中没有pop操作而且后面我们还需要逆序输出//因此比较麻烦这里我们就不用 StackString 直接使用 ListString s2//StackString s2 new StackString(); // 储存中间结果的栈s2ListString s2 new ArrayListString(); // 储存中间结果的Lists2//遍历lsfor(String item: ls) {//如果是一个数加入s2if(item.matches(\\d)) {s2.add(item);} else if (item.equals(()) {s1.push(item);} else if (item.equals())) {//如果是右括号“)”则依次弹出s1栈顶的运算符并压入s2直到遇到左括号为止此时将这一对括号丢弃while(!s1.peek().equals(()) {s2.add(s1.pop());}s1.pop();//!!! 将 ( 弹出 s1栈 消除小括号} else {//当item的优先级小于等于s1栈顶运算符, 将s1栈顶的运算符弹出并加入到s2中再次转到(4.1)与s1中新的栈顶运算符相比较//问题我们缺少一个比较优先级高低的方法while(s1.size() ! 0 Operation.getValue(s1.peek()) Operation.getValue(item) ) {s2.add(s1.pop());}//还需要将item压入栈s1.push(item);}}//将s1中剩余的运算符依次弹出并加入s2while(s1.size() ! 0) {s2.add(s1.pop());}return s2; //注意因为是存放到List, 因此按顺序输出就是对应的后缀表达式对应的List}执行
public static void main(String[] args) {//完成将一个中缀表达式转成后缀表达式的功能//说明//1. 1((23)×4)-5 转成 1 2 3 4 × 5 –//2. 因为直接对str 进行操作不方便因此 先将 1((23)×4)-5 》 中缀的表达式对应的List// 即 1((23)×4)-5 ArrayList [1,,(,(,2,,3,),*,4,),-,5]//3. 将得到的中缀表达式对应的List 后缀表达式对应的List// 即 ArrayList [1,,(,(,2,,3,),*,4,),-,5] 》 ArrayList [1,2,3,,4,*,,5,–]String expression 1((23)*4)-5;//注意表达式ListString infixExpressionList toInfixExpressionList(expression);System.out.println(中缀表达式对应的List infixExpressionList); // ArrayList [1,,(,(,2,,3,),*,4,),-,5]ListString suffixExpreesionList parseSuffixExpreesionList(infixExpressionList);System.out.println(后缀表达式对应的List suffixExpreesionList); //ArrayList [1,2,3,,4,*,,5,–]System.out.printf(expression%d, calculate(suffixExpreesionList)); // ?/*//先定义给逆波兰表达式//(304)×5-6 30 4 5 × 6 - 164// 4 * 5 - 8 60 8 / 2 4 5 * 8 - 60 8 2 / //测试//说明为了方便逆波兰表达式 的数字和符号使用空格隔开//String suffixExpression 30 4 5 * 6 -;String suffixExpression 4 5 * 8 - 60 8 2 / ; // 76//思路//1. 先将 3 4 5 × 6 - 放到ArrayList中//2. 将 ArrayList 传递给一个方法遍历 ArrayList 配合栈 完成计算ListString list getListString(suffixExpression);System.out.println(rpnList list);int res calculate(list);System.out.println(计算的结果是 res);*/
}原文在这里