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

时间:2023-02-09 10:41:13
要实现一个简单的计算器很容易:维护一个操作栈和一个数据栈。

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

测试用题: 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();
}
}