算数表达式求值(中缀表达式转后缀表达式并求值)

中缀表达式转后缀表达式的规则:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈(如果此时栈顶的运算符为"(",则将这个运算符也压入栈中)
6.最终将栈中的元素依次出栈,输出

具体代码实现:

第一步:中缀表达式转后缀表达式

  1 package data.struct.algorithm;
  2
  3 import java.io.BufferedReader;
  4 import java.io.IOException;
  5 import java.io.InputStreamReader;
  6
  7 //定义栈,用于存放转换过程中的操作符
  8 class StackFix {
  9     // 栈的大小
 10     private int maxSize;
 11     // 数组模拟栈
 12     private char stackArr[];
 13     // 栈顶指针
 14     private int top;
 15
 16     // 构造函数初始化栈
 17     public StackFix(int s) {
 18         maxSize = s;
 19         stackArr = new char[maxSize];
 20         top = -1;
 21     }
 22
 23     // 进栈
 24     public void push(char value) {
 25         stackArr[++top] = value;
 26     }
 27
 28     // 出栈
 29     public char pop() {
 30         return stackArr[top--];
 31     }
 32
 33     // 显示栈顶元素
 34     public char peek() {
 35         return stackArr[top];
 36     }
 37
 38     // 判断栈是否为空
 39     public boolean isEmpty() {
 40         return top == -1;
 41     }
 42 }
 43
 44 // 转换类
 45 class InTranstoPost {
 46     private StackFix theStackFix;
 47     private String input;
 48     private String output = "";
 49
 50     // 初始化
 51     public InTranstoPost(String in) {
 52         input = in;
 53         int stackSize = input.length();
 54         theStackFix = new StackFix(stackSize);
 55     }
 56
 57     // 主要转换功能函数
 58     public String doTran() {
 59         for (int j = 0; j < input.length(); j++) {
 60             // 获取一个输入字符串的一个字符
 61             char ch = input.charAt(j);
 62             switch (ch) {
 63
 64             case ‘+‘:
 65             case ‘-‘:
 66                 // 如果字符为‘+‘或者‘-‘,若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数1为运算符的优先级
 67                 gotOper(ch, 1);
 68                 break;
 69             case ‘*‘:
 70             case ‘/‘:
 71                 // 如果字符为‘*‘或者‘/‘,若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数2为运算符的优先级
 72                 gotOper(ch, 2);
 73                 break;
 74             case ‘(‘:
 75                 // 如果字符为‘(‘,则压入栈中
 76                 theStackFix.push(ch);
 77                 break;
 78             case ‘)‘:
 79                 // 如果字符为‘)‘,则弹出栈顶元素,如果栈顶元素为‘(‘,则结束循环,输出转换结果,否则依次弹出栈顶元素并输出,
 80                 // 直到碰到‘(‘
 81                 gotRbracket(ch);
 82                 break;
 83             default:
 84                 // 字符为操作数,不入栈,直接输出
 85                 output = output + ch;
 86                 break;
 87             }
 88         }
 89         // 判断输入的字符串的每一个字符的循环结束,依次弹出栈中的元素,并输出
 90         while (!theStackFix.isEmpty()) {
 91             output = output + theStackFix.pop();
 92         }
 93         return output;
 94     }
 95
 96     // 该函数用于字符为‘)‘时的相应操作
 97     public void gotRbracket(char ch) {
 98         while (!theStackFix.isEmpty()) {
 99             char chx = theStackFix.pop();
100             if (chx == ‘(‘) {
101                 break;
102             } else {
103                 output = output + chx;
104             }
105         }
106     }
107
108     // 非‘)‘字符的其他操作符的处理
109     public void gotOper(char opThis, int prec1) {
110         while (!theStackFix.isEmpty()) {
111             char opTop = theStackFix.pop();
112             if (opTop == ‘(‘) {
113                 theStackFix.push(opTop);
114                 break;
115             } else {
116                 int prec2;
117                 if (opTop == ‘+‘ || opTop == ‘-‘) {
118                     prec2 = 1;
119                 } else {
120                     prec2 = 2;
121                 }
122                 if (prec2 < prec1) {
123                     theStackFix.push(opTop);
124                     break;
125                 } else {
126                     output = output + opTop;
127                 }
128             }
129         }
130         // 栈空,字符直接压入栈中
131         theStackFix.push(opThis);
132     }
133 }
134
135 // 主函数
136 public class InfixToPostFix {
137
138     /**
139      * @param args
140      * @throws IOException
141      */
142     public static void main(String[] args) throws IOException {
143
144         // 定义两个字符串,一个接收键盘输入,一个用于代表转换后的字符串
145         String input, output;
146         while (true) {
147             System.out.println("Enter a InFix:");
148             System.out.flush();
149             // getString()函数,从键盘获取输入的中缀表达式字符串
150             input = getString();
151             // 输入的字符串为空,结束判断
152             if (input.equals("")) {
153                 break;
154             }
155             // 进行转换
156             InTranstoPost tran = new InTranstoPost(input);
157             output = tran.doTran();
158             System.out.println("Thr Postfix is " + output);
159         }
160     }
161
162     // 键盘获取输入的方式,常用做法
163     public static String getString() throws IOException {
164         InputStreamReader isr = new InputStreamReader(System.in);
165         BufferedReader bufr = new BufferedReader(isr);
166         String s = bufr.readLine();
167         return s;
168     }
169 }
时间: 2024-11-05 14:49:28

算数表达式求值(中缀表达式转后缀表达式并求值)的相关文章

运用栈把算术表达式+,-,*,/,%(中缀表达式)转换成后缀表达式并且计算出值

原理: 1.首先判断是数值还是符号,如果是数值放进字符数组以#表示结束, 2.如果是符号,放进栈, 3.每个符号之间要比较优先级,如果栈顶符号优先级低,符号进栈,如果相等(即“(” “)”)出栈,栈顶符号优先级高,栈顶元素出栈进入字符数组,得到后缀表达式 4.计算后缀表达式,判断是数字还是符号.直到遇到符号,将前面的数字计算后放进栈,一直重复,知道“\0” 代码(局限用整数,因为有模运算,若要任何类型的代码,我的blog有) 1 #include <stdio.h> 2 #include &l

C++用后缀表达式(逆波兰)求四则表达式值,采用STL中的stack

简介: 20 世纪50 年代, 波兰逻辑学家JanLukasiewicz ,想到了一种不需要括号的后缀表达法,我们也把它称为逆波兰( Reverse Polish Notation, RPN) 表示,对于"如9 + (3 -1 ) X3 +10-/2 " ,如果要用后缀表示法应该是: "9 3 1-3*+10 2 / + " ,这样的表达式称为后缀表达式. 中缀表达式转后缀表达式规则: 从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分

中缀表达式转后缀表达式(Java代码实现)

后缀表达式求值 后缀表达式又叫逆波兰表达式,其求值过程可以用到栈来辅助存储.例如要求值的后缀表达式为:1 2 3 + 4 * + 5 -,则求值过程如下: 遍历表达式,遇到数字时直接入栈,栈结构如下 2. 接着读到 “+”操作符,则将栈顶和次栈顶元素出栈与操作符进行运算,执行 2 + 3操作,并将结果5压入栈中,此时栈结构如下 3.  继续读到4,是数字则直接压栈,此时栈结构如下 4. 继续向后读取,此时读取到操作符“*”,则将栈顶和次栈顶元素出栈与操作符进行运算,即执行 5 * 4 ,然后将结

sicily 中缀表达式转后缀表达式

题目描述 将中缀表达式(infix expression)转换为后缀表达式(postfix expression).假设中缀表达式中的操作数均以单个英文字母表示,且其中只包含左括号'(',右括号‘)’和双目算术操作符+,-,*,/. 输入格式 第一行是测试样例个数n.以下n行,每行是表示中缀表达式的一个字符串(其中只包含操作数和操作符和左右括号,不包含任何其他字符),长度不超过100个字符. 输出格式 为每一个测试样例单独一行输出对应后缀表达式字符串(其中只包含操作数和操作符,不包含任何其他字符

算术表达式的前缀表达式,中缀表达式和后缀表达式

这里所谓的前缀,中缀,后缀是根据操作符的位置来定的,如果操作符在操作数前面,则称为前缀表达式,例如"- + 1 × + 2 3 4 5";如果操作符在操作数之间,则称为中缀表达式,例如 "1+((2+3)×4)-5";如果操作符在操作数后面,则称为后缀表达式,例如"1 2 3 + 4 × + 5 -". 虽然中缀表达式符合人类的日常思维习惯,但是计算机在存储中缀表达式时,需要使用树这种数据结构,如果表达式过于复杂,那么树的高度会变得很高,大大增加

利用栈将中缀表达式转为后缀表达式

#include<iostream>#include<stdio.h>using namespace std;#include<stack>const int SM = 40;int Precedence(char op){    //返回运算符op所对应的优先级数值    switch (op){    case '+':    case '-':return 1;//定义加减运算的优先级为1    case '*':    case '/':return 2;//定

前中后缀表达式以及表达式树

中缀表达式就是我们平时喜闻乐见的形式:二元运算符在中间,它的两个操作数在两侧: a + b * c + ( d * e + f ) * g 后缀和前缀表达式,顾名思义就是把运算符分别放在前面或者后面,注意没有括号,手工转换方法是按运算顺序添加括号,然后把相应的运算符置于相应的括号的前或后,如: ((a + ( b * c)) + (((d * e) + f) * g)) 放到前面有: +(+(a*(b c))*(+((*(d e))f)g)) 放到后面有: ((a(b c)*)+(((d e)*

Java实现后缀表达式建立表达式树

概述 表达式树的特点:叶节点是操作数,其他节点为操作符.由于一般的操作符都是二元的,所以表达式树一般都是二叉树. 根据后缀表达式"ab+cde+**"建立一颗树 文字描述: 如同后缀表达式求值一样,逐个读取后缀表达式的每一个符号,如果遇到操作数,建立一个节点把操作数的值加入这个节点,并把节点入栈:如果遇到操作符,弹出栈里的两个节点,并赋值为自己的左子节点.右子节点,最后把这个节点树入栈. 画图描述: 1.读入操作数a,创建节点,压入栈:读入操作数b,创建节点,压入栈 2.遇到操作符&q

深入浅出数据结构C语言版(8)——后缀表达式、栈与四则运算计算器

在深入浅出数据结构(7)的末尾,我们提到了栈可以用于实现计算器,并且我们给出了存储表达式的数据结构(结构体及该结构体组成的数组),如下: //SIZE用于多个场合,如栈的大小.表达式数组的大小 #define SIZE 1000 //表达式的单个元素所使用的结构体 typedef struct elem { int num = 0; //若元素存储操作数则num为该操作数 char oper = '='; //若元素存储操作符则oper为该操作符 bool IsNum = false; //用于

[题解]P1449 后缀表达式

[题解]P1449 后缀表达式(栈) 题目链接:P1449 后缀表达式 题目描述: 所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级). 如:3(5–2)+7对应的后缀表达式为:3.5.2.-7.[email protected].'@'为表达式的结束符号.'.'为操作数的结束符号. 输入格式:输入:后缀表达式 输出格式:输出:表达式的值 输入输出样例: 输入 #1 3.5.2.-*[e