栈的应用二--四则运算表达式求值(逆波兰表示:后缀表达式)
2016-05-03 19:56
681 查看
栈的应用一–斐波那契(Fibonacci)数列的实现(代码)
中缀表达式,我们把平时所用的标准的四则运算表达式“9+()3-1)*3+10/2”叫做中缀表达式。
后缀表达式,所有的符号都是在要运算的数字的后面出现:9 3 1 - 3 * + 10 2 / + ;我们也叫它:逆波兰表示(Reverse Polish Notation,RPN)
中缀表达式,我们把平时所用的标准的四则运算表达式“9+()3-1)*3+10/2”叫做中缀表达式。
后缀表达式,所有的符号都是在要运算的数字的后面出现:9 3 1 - 3 * + 10 2 / + ;我们也叫它:逆波兰表示(Reverse Polish Notation,RPN)
将中缀表达式转换为后缀表达式:
规则:从左到右便利中缀表达式的每一个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先加减,若优先级相同,则看先后顺序:由于是自左向右运算所以先进展的要先与后进的)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。后缀表达式的计算结果:
规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号就将处于栈顶的两个数字出栈,进行运算,运算结果进展,一直到获得最终结果。代码实现:
package com.sfd.use; import java.util.HashMap; import java.util.Map; import java.util.Stack; public class RPN { // 保存运算符的优先级 private static Map<Character, Integer> map = new HashMap<Character, Integer>(); static { map.put('*', 2); map.put('/', 2); map.put('+', 1); map.put('-', 1); map.put(')', 3); map.put('(', 0); } public static void main(String[] args) { String string = "9+((3-15)*2)+3*3+10/2"; // 将中缀表达式转换成后缀表达式 String houzhui = change(string); System.out.println("string:" + houzhui); // 得到计算结果 System.out.println(compute(houzhui)); } public static double compute(String string) { int result = 0; String[] strings = string.split(" "); Stack<String> stack = new Stack<String>(); String n1 = ""; String n2 = ""; for (String s : strings) { // System.out.println(s); if (s.matches("^\\d*$")) { System.out.println(s); stack.push(s); } else { System.out.println(s); // 匹配运算符字符串,进行相应的运算 switch (s) { case "+": n1 = stack.pop(); n2 = stack.pop(); result = Integer.parseInt(n2) + Integer.parseInt(n1); break; case "-": n1 = stack.pop(); n2 = stack.pop(); result = Integer.parseInt(n2) - Integer.parseInt(n1); break; case "*": n1 = stack.pop(); n2 = stack.pop(); result = Integer.parseInt(n2) * Integer.parseInt(n1); break; case "/": n1 = stack.pop(); n2 = stack.pop(); result = Integer.parseInt(n2) / Integer.parseInt(n1); break; default: break; } stack.push(result + ""); } System.out.println("result:" + result); } return result; } // 将中缀表达式转化成后缀表达式 public static String change(String string) { Stack<Character> stack = new Stack<Character>(); char[] chars = string.toCharArray(); StringBuffer sb = new StringBuffer(); for (char c : chars) { System.out.println(stack); System.out.println(sb.toString()); // 判断是否是数字如果是数字追加到StringBuffer中 if (c >= '0' && c <= '9') { sb.append(c); } else { // 数字和运算符 if (!(sb.charAt(sb.length() - 1) == ' ')) { sb.append(" "); } // 判断栈是否为空,当栈空时直接将当前的运算压进栈中 if (stack.empty()) { stack.push(c); continue; } // 当当前字符')' 则栈顶元素依次输出,直到')'为止 if (c == ')') { while (stack.peek() != '(') { System.out.println(stack.peek()); char cc = stack.pop(); sb.append(cc + " "); } stack.pop(); continue; } //如果当前运算符的优先级低于栈顶运算符的优先级那么弹出栈顶的运算符,并将当前的运算符压进栈中;直到栈顶元素为'(' else if (map.get(c) <= map.get(stack.peek())&&stack.peek()!='(') { while (!stack.isEmpty() && map.get(c) <= map.get(stack.peek())) { System.out.println(c); char cc = stack.pop(); if (cc != '(') { sb.append(cc + " "); }else{ break; } } stack.push(c); } // 如果当前运算符的优先级高于栈顶运算符的优先级那么直接压进栈中 else { stack.push(c); } } } //将栈中剩余的运算符追加到表达式尾部 while (!stack.isEmpty()) { sb.append(" " + stack.pop()); } return sb.toString(); } }
相关文章推荐
- 9.二进制中1的个数
- HDOJ(HDU) 2135 Rolling table
- halcon学习笔记——机器视觉工程应用的开发思路
- 二、进程调度算法
- HDOJ(HDU) 2135 Rolling table
- JAVA - 优雅的记录日志(log4j实战篇)
- FPGA第八篇:运算符、赋值语句和结构说明语句
- 向JAVA项目中导入jar包,需要进行设置。(安卓项目可直接导入)
- Linux文件分割与合并:split & cat命令
- 第89课:Spark Streaming on Kafka解析和安装实战
- UDP socket通讯
- 计算机网络自顶向下方法之——第二章 之四
- 硬件工程师-面试笔记0305
- hdu 1274 展开字符串
- Linux学习笔记之三
- [Java基础] Java四类八种基本类型
- DELL服务器IPMI管理界面无法登录问题解决
- 3Sum leetcode第15题 Java代码
- 多态的实质、利弊、使用条件、类型、instanceof
- 数据流图