算数表达式求值(中缀表达式转后缀表达式并求值)
2016-04-10 15:57
597 查看
中缀表达式转后缀表达式的规则:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈(如果此时栈顶的运算符为"(",则将这个运算符也压入栈中)
6.最终将栈中的元素依次出栈,输出
具体代码实现:
第一步:中缀表达式转后缀表达式
第二步:后缀表达式求值
在这里,我的程序没有使用上一步获取的转换后的字符串,而是继续接收用户额输入,如果使用上一步的结果,则程序会变得更简单一些
求值的步骤:
(1)设置一个栈,开始时,栈为空,然后从左到右扫描后缀表达式
(2)若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的 放到运算符左边,运算后的结果再进栈
(3)直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果,弹出栈即可得到结果。
具体代码实现:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈(如果此时栈顶的运算符为"(",则将这个运算符也压入栈中)
6.最终将栈中的元素依次出栈,输出
具体代码实现:
第一步:中缀表达式转后缀表达式
package data.struct.algorithm; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; //定义栈,用于存放转换过程中的操作符 class StackFix { // 栈的大小 private int maxSize; // 数组模拟栈 private char stackArr[]; // 栈顶指针 private int top; // 构造函数初始化栈 public StackFix(int s) { maxSize = s; stackArr = new char[maxSize]; top = -1; } // 进栈 public void push(char value) { stackArr[++top] = value; } // 出栈 public char pop() { return stackArr[top--]; } // 显示栈顶元素 public char peek() { return stackArr[top]; } // 判断栈是否为空 public boolean isEmpty() { return top == -1; } } // 转换类 class InTranstoPost { private StackFix theStackFix; private String input; private String output = ""; // 初始化 public InTranstoPost(String in) { input = in; int stackSize = input.length(); theStackFix = new StackFix(stackSize); } // 主要转换功能函数 public String doTran() { for (int j = 0; j < input.length(); j++) { // 获取一个输入字符串的一个字符 char ch = input.charAt(j); switch (ch) { case '+': case '-': // 如果字符为'+'或者'-',若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数1为运算符的优先级 gotOper(ch, 1); break; case '*': case '/': // 如果字符为'*'或者'/',若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数2为运算符的优先级 gotOper(ch, 2); break; case '(': // 如果字符为'(',则压入栈中 theStackFix.push(ch); break; case ')': // 如果字符为')',则弹出栈顶元素,如果栈顶元素为'(',则结束循环,输出转换结果,否则依次弹出栈顶元素并输出, // 直到碰到'(' gotRbracket(ch); break; default: // 字符为操作数,不入栈,直接输出 output = output + ch; break; } } // 判断输入的字符串的每一个字符的循环结束,依次弹出栈中的元素,并输出 while (!theStackFix.isEmpty()) { output = output + theStackFix.pop(); } return output; } // 该函数用于字符为')'时的相应操作 public void gotRbracket(char ch) { while (!theStackFix.isEmpty()) { char chx = theStackFix.pop(); if (chx == '(') { break; } else { output = output + chx; } } } // 非')'字符的其他操作符的处理 public void gotOper(char opThis, int prec1) { while (!theStackFix.isEmpty()) { char opTop = theStackFix.pop(); if (opTop == '(') { theStackFix.push(opTop); break; } else { int prec2; if (opTop == '+' || opTop == '-') { prec2 = 1; } else { prec2 = 2; } if (prec2 < prec1) { theStackFix.push(opTop); break; } else { output = output + opTop; } } } // 栈空,字符直接压入栈中 theStackFix.push(opThis); } } // 主函数 public class InfixToPostFix { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // 定义两个字符串,一个接收键盘输入,一个用于代表转换后的字符串 String input, output; while (true) { System.out.println("Enter a InFix:"); System.out.flush(); // getString()函数,从键盘获取输入的中缀表达式字符串 input = getString(); // 输入的字符串为空,结束判断 if (input.equals("")) { break; } // 进行转换 InTranstoPost tran = new InTranstoPost(input); output = tran.doTran(); System.out.println("Thr Postfix is " + output); } } // 键盘获取输入的方式,常用做法 public static String getString() throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader bufr = new BufferedReader(isr); String s = bufr.readLine(); return s; } }
第二步:后缀表达式求值
在这里,我的程序没有使用上一步获取的转换后的字符串,而是继续接收用户额输入,如果使用上一步的结果,则程序会变得更简单一些
求值的步骤:
(1)设置一个栈,开始时,栈为空,然后从左到右扫描后缀表达式
(2)若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的 放到运算符左边,运算后的结果再进栈
(3)直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果,弹出栈即可得到结果。
具体代码实现:
package data.struct.algorithm; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; class Stackfix2 { private int maxSize; private int stackArr[]; private int top; public Stackfix2(int maxSize) { this.maxSize = maxSize; stackArr = new int[maxSize]; top = -1; } // 进栈 public void push(int value) { stackArr[++top] = value; } // 出栈 public int pop() { return stackArr[top--]; } // 显示栈顶元素 public int peek() { return stackArr[top]; } // 判断栈是否为空 public boolean isEmpty() { return top == -1; } public boolean isFull() { return top == maxSize - 1; } } class Postfix { private Stackfix2 theStackfix2; private String input; public Postfix(String in) { input = in; } public int doCalculate() { int num1; int num2; int inresult; char ch; int j; theStackfix2 = new Stackfix2(20); for (j = 0; j < input.length(); j++) { ch = input.charAt(j); // 如果字符为整数,则进行类型强制转换,并压入栈中 if (ch >= '0' && ch <= '9') { theStackfix2.push((int) (ch - '0')); } else { // 测试用例最最关键的位置,考虑计算过程中的操作数的位置 // 先弹出栈的元素是第二个操作数,后弹出栈的是第一个操作数 num2 = theStackfix2.pop(); num1 = theStackfix2.pop(); switch (ch) { case '+': inresult = num1 + num2; break; case '-': inresult = num1 - num2; break; case '*': inresult = num1 * num2; break; case '/': inresult = num1 / num2; break; default: inresult = 0; break; } theStackfix2.push(inresult); } } return theStackfix2.pop(); } } public class PostfixValue { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { while (true) { System.out.println("Enter a Postfix:"); System.out.flush(); String input; int result; input = getString(); Postfix parse = new Postfix(input); result = parse.doCalculate(); System.out.println("Postfix求值的结果是:" + result); } } public static String getString() throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader bufr = new BufferedReader(isr); return bufr.readLine(); } }
相关文章推荐
- 81、去除标题栏 Activity 和 AppCompatActivity
- CSS3_文本效果&字体
- codeforces 650c
- 分布式监控系统Ganglia简介及安装
- Windows 10 iso
- 数据库设计 Step by Step (1)——扬帆启航
- 设计模式之装饰器模式
- 导航控制器实例——锤子标签
- Android 通过webservice上传多张图片到指定服务器上面
- RecyclerView.Adapter优化了吗?
- maven+srping+springmvc+mybatis的环境搭建的每一步和代码
- 构造方法实验代码
- 可执行程序的装载
- *windows.event对象在ie与ff中的区别**
- 剑指offer系列之5:用两个栈来实现队列
- shell uniq 和sort 简单用法及实例
- Git入门
- 区间调度问题
- 冒泡排序、选择和插入排序、二分法查找
- servlet/filter/listener/interceptor区别与联系