【九度OJ】1019【栈】
2014-08-11 14:04
197 查看
编写一个简易计算器,简易体现在无小数,无负数,无括号运算,并且表达式中操作数和操作符是由空格分开的,处理起来比较方便。整体难度不大,只要弄清计算表达式的原理即可。
我是先将中缀表达式变为后缀表达式,再计算后缀表达式。使用栈和队列。80MS,最好的70MS。
原理:
1.中缀表达式-->后缀表达式
操作数直接写入后缀表达式,若为操作符,其优先级小于等于栈顶元素的优先级时,弹出优先级比它大的所有操作符。
直到该操作符优先级大于栈顶元素优先级。这时,将其压入栈中。 表达式遍历完毕时,将栈中所有元素弹出放入后缀表达式中 (先弹出的先放在后缀表达式末尾)
2.后缀表达式计算
从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
注意最后取精度的时候用的BigDecimal
代码:
我是先将中缀表达式变为后缀表达式,再计算后缀表达式。使用栈和队列。80MS,最好的70MS。
原理:
1.中缀表达式-->后缀表达式
操作数直接写入后缀表达式,若为操作符,其优先级小于等于栈顶元素的优先级时,弹出优先级比它大的所有操作符。
直到该操作符优先级大于栈顶元素优先级。这时,将其压入栈中。 表达式遍历完毕时,将栈中所有元素弹出放入后缀表达式中 (先弹出的先放在后缀表达式末尾)
2.后缀表达式计算
从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
注意最后取精度的时候用的BigDecimal
代码:
package Test1; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigDecimal; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; import java.util.StringTokenizer; public class Test12_1019 { /** * by qr jobdu 1019 2014-8-10(11) * * @throws IOException */ public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); HashMap<String,Integer> map=new HashMap<String,Integer>(); //<操作符,优先级> map.put("#", 1); map.put("+", 2); map.put("-", 2); map.put("*", 3); map.put("/", 3); String nifixExp = ""; // 中缀表达式 while (!(nifixExp = br.readLine()).equals("0")) { Stack<String> stack=new Stack<String>(); //!Java 集合类 stack.push("#"); //#在栈底,优先级最低 Queue<String> queue=new LinkedList<String>(); //! // 后缀表达式 StringTokenizer st = new StringTokenizer(nifixExp); //!遍历中缀表达式 String s=""; while (st.hasMoreTokens()) { s = st.nextToken(); if (isDigit(s)) { //是数字 queue.add(s); }else{ //是操作符 String fe=stack.peek(); //只看不删 int priority=map.get(s); while(priority<=map.get(fe)){ queue.add(stack.pop()); fe=stack.peek(); //勿忘重新赋值,指向下一个 } stack.push(s); //优先级大于栈顶元素时,入栈 } } while(!stack.isEmpty()){ queue.add(stack.pop()); //栈底的#也放在后缀表达式末尾了 } while((s=queue.poll())!="#"){ //remove() 和 poll() 方法仅在队列为空时其行为有所不同:remove() 方法抛出一个异常,而 poll() 方法则返回 null。 if(isDigit(s)){ //是数字 stack.push(s); }else{ //是操作符 String operand2=stack.pop(); String operand1=stack.pop(); stack.push(calculate(operand1,operand2,s)); //第一个操作数,第二个操作数,操作符 } } //output String result=stack.pop(); //结果,保留后两位输出 // System.out.println(String.format("%2f",result)); 不行,如果本身没有那么多小数位,则会报错 System.out.println(new BigDecimal(result).setScale(2,BigDecimal.ROUND_HALF_UP)); } } private static String calculate(String operand1, String operand2, String operator) { switch (operator.charAt(0)) { case '+': return Double.parseDouble(operand1)+ Double.parseDouble(operand2)+""; //都要变成double,因为中间操作数可能变成double case '-': return Double.parseDouble(operand1)- Double.parseDouble(operand2)+""; case '*': return Double.parseDouble(operand1)* Double.parseDouble(operand2)+""; case '/': return Double.parseDouble(operand1)/ Double.parseDouble(operand2)+""; //保留两位 default: return "0"; } } private static boolean isDigit(String s) { //判断是否为数字 if (!s.equals("+") && !s.equals("-") && !s.equals("*") && !s.equals("/")) { return true; } return false; } }
相关文章推荐
- 九度OJ 题目1019:简单计算器
- <九度 OJ>题目1019:简单计算器
- 【九度oj】1019简单计算器
- 九度OJ 1019 简单计算器
- 九度OJ 1019 简单计算器 -- 2006年浙江大学计算机及软件工程研究生机试真题
- 九度OJ 1019 简单计算器 -- 2006年浙江大学计算机及软件工程研究生机试真题
- 九度oj 1153,1019 栈
- 九度 OJ 题目1019:简单计算器
- 九度oj 题目1019:简单计算器 【ZJU2006考研机试题5】
- 九度OJ 1019:简单计算器 (基础题、DP)
- 九度OJ 1019:简单计算器
- 九度OJ题目1019:简单计算器(看到一神代码)
- 九度oj-1019:简单计算器
- 九度OJ 1019:简单计算器 (基础题、DP)
- 数字操作符九度OJ 1019 简单计算器
- 九度oj-1019-简单计算器
- 九度OJ-1019简单计算器
- 九度OJ题目1019:简单计算器
- 九度OJ 1019 简单计算器
- 九度OJ-题目1019:简单计算器