Java简单计算器(栈实现)

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

最近在复习数据结构,就用栈实现了一个简单计算器,增加了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;
        }
    }
}

运行结果 :

在这里插入图片描述

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值