数据结构复习(二)—— 栈

要实现一个简单的计算器很容易:维护一个操作栈和一个数据栈。

但写出让自己满意的代码挺难。 这是我的最终稿

测试用题: hdu 1237

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashMap;
import java.util.Stack;

class Operator {
    char symbol;
    int priority;
    public Operator() {
    }
    public Operator(char newSymbol, int newPriority) {
        this.symbol = newSymbol;
        this.priority = newPriority;
    }
    public int getPriority() {
        return this.priority;
    }
    public char getSymbol() {
        return this.symbol;
    }
}

class Calculator {
    
    static HashMap<Character, Integer> priority =
            new HashMap<Character, Integer>() {{
                put('+', 2 );
                put('-', 2 );
                put('*', 3 );
                put('/', 3 );
                put('(', 0);
            }};
            
    Stack<Double> dataStack = new Stack<Double>();
    Stack<Character> opStack = new Stack<Character>();
    
    public void reset() {
        dataStack.clear();
        opStack.clear();
    }
    
    public void pushData(double data) {
        dataStack.push(data);
    }
    
    public void handleOp(char op) {
        if(op == '(') {
            opStack.push(op);
        } else if(op == ')') {
            while (!opStack.empty()) {
                char top = opStack.pop();
                if(top != '(') {
                    cal(top);
                } else {
                    break;
                }
            }
        } else {
            while(!opStack.empty()) {
                char top = opStack.peek();
                if(priority.get(top) >= priority.get(op)) {
                    cal(top);
                    opStack.pop();
                }else {
                    break;
                }
            }
            opStack.push(op);
        }
    }
    
    private void cal(char op) {
        double data1;
        double data2;
        data2 = dataStack.pop();
        data1 = dataStack.pop();
        switch(op) {
        case '*':
            dataStack.push(data1*data2);
            break;
        case '/':
            dataStack.push(data1/data2);
            break;
        case '+':
            dataStack.push(data1+data2);
            break;
        case '-':
            dataStack.push(data1-data2);
            break;
        }
    }
    
    public double getResult() {
        while(!opStack.isEmpty()) {
            char top = opStack.pop(); // shoud be only '+-*/'left
            cal(top);
        }
        return dataStack.pop();
    }
}

public class Main {
    
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        StreamTokenizer in = new StreamTokenizer(
                new BufferedReader(new InputStreamReader(System.in)));
        in.eolIsSignificant(true);
        in.ordinaryChar('/');
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        
        Calculator calculator = new Calculator();
        
        int token = in.nextToken();
        while(token != StreamTokenizer.TT_EOF) {
            int count = 0;
            while(token != StreamTokenizer.TT_EOL) {
                count++;
                if (token == StreamTokenizer.TT_NUMBER) {
                    calculator.pushData(in.nval);
                } else {
//                    System.out.println((char)token);
                    calculator.handleOp((char)token);
                }
                token = in.nextToken();
            }
            double result = calculator.getResult();
            if(count == 1 && result == 0) {
                break;
            }
            out.printf("%.2f\r\n", result);
            
            calculator.reset();
            token = in.nextToken();
        }
        out.flush();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值