最近在复习数据结构,就用栈实现了一个简单计算器,增加了AWT的图形界面.
例:输入一个字符串:3*2+1-2
解题思路:
定义两个栈,一个用来存放数字,另一个用来存放操作符.
遍历字符串,如果是数字,就放入数字栈,
如果是操作符,则分两种情况:
- 1.若字符栈为空,则直接入栈
- 2.字符栈不为空,需要比较当前要入栈的字符和字符栈顶的字符的优先级
- 如果前者优先级小于后者, 则需要进行计算(从数字栈取两个值,字符栈取一个值进行计算) ,计算完成之后将结果入数字栈, 再继续判断要入栈的字符和字符栈顶的字符的优先级.
- 如果前者优先级大于后者, 当前字符入字符栈, 记录一个标志位, 下一个数字入栈之后进行计算.(从数字栈取两个值,字符栈取一个值进行计算).
如何判断计算完:
- 字符栈为空
最后全部计算完之后,将结果入数字栈,返回该结果即可.
附上代码:
import java.awt.*;
import java.awt.event.*;
import java.util.Stack;
public class Calculator {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends Frame {
Button btn0,btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,add,min,mul,div,equal,clear,delete;
TextField tx;
public MyFrame() {
/**
* 1.添加按钮 文本框
* 2.添加事件监听
*/
//添加组件 10个数字 5个运算符 一个文本框 一个清零按钮 一个删除按钮
btn0 = new Button("0");
btn1 = new Button("1");
btn2 = new Button("2");
btn3 = new Button("3");
btn4 = new Button("4");
btn5 = new Button("5");
btn6 = new Button("6");
btn7 = new Button("7");
btn8 = new Button("8");
btn9 = new Button("9");
add = new Button("+");
min = new Button("-");
mul = new Button("*");
div = new Button("/");
equal = new Button("=");
clear = new Button("clear");
delete = new Button("<-");
tx = new TextField("");
//添加一个面板
Panel panel = new Panel();
//设置面板布局
panel.setLayout(new GridLayout(5,3));
panel.add(btn1);
panel.add(btn2);
panel.add(btn3);
panel.add(btn4);
panel.add(btn5);
panel.add(btn6);
panel.add(btn7);
panel.add(btn8);
panel.add(btn9);
panel.add(add);
panel.add(btn0);
panel.add(min);
panel.add(mul);
panel.add(div);
panel.add(delete);
//将面板添加到Frame中心
add(panel,BorderLayout.CENTER);
//将文本框添加到Frame
add(tx,BorderLayout.NORTH);
add(panel);
add(clear,BorderLayout.WEST);
add(equal,BorderLayout.EAST);
//添加事件监听
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
MyActionListen myActionListen = new MyActionListen();
add.addActionListener(myActionListen);
min.addActionListener(myActionListen);
mul.addActionListener(myActionListen);
div.addActionListener(myActionListen);
clear.addActionListener(myActionListen);
delete.addActionListener(myActionListen);
equal.addActionListener(myActionListen);
btn0.addActionListener(myActionListen);
btn1.addActionListener(myActionListen);
btn2.addActionListener(myActionListen);
btn3.addActionListener(myActionListen);
btn4.addActionListener(myActionListen);
btn5.addActionListener(myActionListen);
btn6.addActionListener(myActionListen);
btn7.addActionListener(myActionListen);
btn8.addActionListener(myActionListen);
btn9.addActionListener(myActionListen);
setVisible(true);
setBounds(100,100,200,300);
setResizable(false);
}
//事件监听
private class MyActionListen implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String text = tx.getText();
if (e.getSource() == btn0) {
text += btn0.getLabel();
tx.setText(text);
}
if (e.getSource() == btn1) {
text += btn1.getLabel();
tx.setText(text);
}
if (e.getSource() == btn2) {
text += btn2.getLabel();
tx.setText(text);
}
if (e.getSource() == btn3) {
text += btn3.getLabel();
tx.setText(text);
}
if (e.getSource() == btn4) {
text += btn4.getLabel();
tx.setText(text);
}
if (e.getSource() == btn5) {
text += btn5.getLabel();
tx.setText(text);
}
if (e.getSource() == btn6) {
text += btn6.getLabel();
tx.setText(text);
}
if (e.getSource() == btn7) {
text += btn7.getLabel();
tx.setText(text);
}
if (e.getSource() == btn8) {
text += btn8.getLabel();
tx.setText(text);
}
if (e.getSource() == btn9) {
text += btn9.getLabel();
tx.setText(text);
}
if (e.getSource() == add) {
text += add.getLabel();
tx.setText(text);
}
if (e.getSource() == min) {
text += min.getLabel();
tx.setText(text);
}
if (e.getSource() == mul) {
text += mul.getLabel();
tx.setText(text);
}
if (e.getSource() == div) {
text += div.getLabel();
tx.setText(text);
}
//计算表达式的结果
if (e.getSource() == equal) {
if(tx.getText()!=null) {
text += equal.getLabel();
tx.setText(text);
double calculate = calculate(tx);
text += calculate;
tx.setText(text);
}
}
//清零按钮
if (e.getSource() == clear) {
tx.setText("");
}
//删除按钮
if (e.getSource() == delete) {
String s = tx.getText();
if (s.length() > 0) {
tx.setText(s.substring(0, s.length() - 1));
}
}
}
/**
* 计算的核心代码
* @param tx
* @return
*/
private double calculate(TextField tx) {
//定义两个栈 用来计算数据
Stack<Double> numStack = new Stack<>();
Stack<Character> charStack = new Stack<>();
//进行计算的标志
boolean flag = false;
//获取文本框的内容
String str = tx.getText();
int begin = 0;
int end = 0;
//遍历s
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (!Character.isDigit(ch)) {
//如果不是数字 ,首先判断字符栈是否为空 将end置为当前位置
end = i;
//将begin 和 end之间的的数字入数字栈
numStack.push(Double.parseDouble(str.substring(begin,end)));
begin = end+1;
if (flag == true) {
double second = numStack.pop();
double first = numStack.pop();
char opt = charStack.pop();
double result = operation(first, second, opt);
//将计算出的结果进行入栈
numStack.push(result);
}
if (!charStack.empty()) {
//非空 判断优先级
if (level(ch, charStack.get(charStack.size() - 1))) {
//优先级高 将flag设置为true 下一步放入数字的时候进行运算
flag = true;
}
}
//进行入栈
if(str.charAt(i) != '=') {
charStack.push(ch);
}
}
}
//全部入栈完成 进行计算
while (!numStack.empty() && !charStack.empty()) {
//从底往上计算
double first = numStack.remove(0);
double second = numStack.remove(0);
char opt = charStack.remove(0);
double result = operation(first, second, opt);
//运算完进行入栈
numStack.add(0,result);
}
return numStack.pop();
}
/**
* 进行计算
* @param first
* @param second
* @param opt
* @return
*/
private double operation(double first, double second, char opt) {
switch (opt) {
case '+':
return first + second;
case '-':
return first - second;
case '*':
return first * second;
case '/':
return first / second;
}
return -1;
}
/**
* 判断ch 和 topCh的优先级
* @param ch
* @param topCh
* @return
*/
private boolean level(char ch, Character topCh) {
switch (ch) {
case '+':
return false;
case '-':
return false;
case '*':
if(topCh == '+' || topCh == '-') {
return true;
}
case '/':
if(topCh == '+' || topCh == '-') {
return true;
}
}
return false;
}
}
}
运行结果 :

本文介绍了使用栈数据结构实现一个简单计算器的过程,包括解析输入字符串、处理数字和操作符、根据优先级进行计算的逻辑,并提供了运行结果。通过AWT创建了图形用户界面。
707





