Java GUI实现的计算器(中缀转后缀,运算有顺序)

Java GUI实现的计算器(中缀转后缀,运算有顺序),第1张

Java GUI实现的计算器(中缀转后缀,运算有顺序) Java GUI实现的计算器(中缀转后缀,运算有顺序) 1、问题描述

本程序支持含负数、小数、多位数等多种 *** 作数的处理,可以计算含加、减、乘、除、求余、求幂等多种运算符(“+”、“-”、“*”、“/”)的表达式,并能判断表达式括号是否匹配;从键盘输入一个正确的中缀表达式,将中缀表达式转换为计算机理解的后缀表达式,计算后缀表达式(运算有顺序)的值。

GUI计算器实现对于表达式中的简单错误,能够给出提示信息的d窗,且不允许错误信息进入表达式;

(2)能够处理多种 *** 作符

(3)实现包含简单运算的计算器

2、算法实现 中缀表达式转为后缀表达式

参考此文章,有配图好理解

①我们使用一个stack栈结构存储 *** 作符,用一个List结构存储后缀表达式结果,使用map结构来判断运算符的优先级;

②首先读取到数字,直接存入list中;

③当读取到左括号"("时,直接压栈,当读取到运算符时,分两种情况讨论;

  • 运算符栈为空,直接入栈

  • 当栈顶 *** 作符的优先级 小于 当前运算符优先级时(如+和-的优先级低于 * 和 /),直接入栈;

  • 当运算符不为空 且 栈顶 *** 作符的优先级 大于或等于 当前运算符优先级时,循环执行出栈 *** 作并加入list中,直到遇到优先级小于当前运算符的元素为止。循环执行完后再将当前运算符压栈。

    PS. 只有遇到右括号时,左括号才出栈;

④当遇到右括号")"时,循环执行出栈 *** 作并加入到list中,直到遇到左括号为止。并将左括号d出,但不加入list中;

⑤表达式的值读取完后,将 *** 作符栈中的所有元素d出并加入到list中;

执行完上面步骤后,list中存储的顺序即为我们转换后的后缀表达式的结果

//中缀表达式转后缀表达式
public void evalRPN() {
    Stack stack = new Stack<>();
    Iterator iterator =  expression.iterator();
    while(iterator.hasNext()) {
        String now = iterator.next();
        System.out.println(now);
        if(isNumeric(now)) {
            suffix.add(now);//数字直接入list
        }else{
            if(stack.isEmpty()) {//判断栈是否为空
                stack.add(now);
                continue;
            }
            if(now.equals("(")) {//括号判断,分情况
                stack.add(now);
            }else if(now.equals(")")) {
                while(true) {
                    if(stack.peek().equals("(")) {
                        stack.pop();
                        break;
                    }else{
                        suffix.add(stack.pop());
                    }
                }
            }else{
                if(map.get(stack.peek()) < map.get(now) || (stack.peek()).equals("(")) {
                    stack.add(now);
                }else{
                    while(true) {
                        suffix.add(stack.pop());
                        if(stack.isEmpty() == true ||map.get(stack.peek()) < map.get(now)) {
                            stack.add(now);
                            break;
                        }
                    }
                }
            }
        }
    }
    suffix.add(stack.pop());
}

碎碎念:迭代器挺好用的

Iterator()方法

无论List、Set、Queue,都有个iterator()方法,定义在Collection接口中,而这些线性表和集合都是继承自Collection接口。iterator()方法会返回java.util.Iterator接口的 *** 作对象(Collection收集的所有对象)。

static void forEach(Collection collection) {
    //借forEach函数来展示迭代器方法
    Iterator iterator = collection.iterator();
    while(iterator.hasNext()) {
        out.println(iterator.next());
    }
}

常用方法

  • Iterator= list.iterator() 将集合list变成迭代器it,接下来就可以 *** 作迭代器的方法了
  • it.hasNext() 查看是否还有下一个元素
  • it.next() 查看一个元素
  • it.remove() 删除当前元素并返回
后缀表达式计算结果

将数字存入stack结构中,从右向左看,遇到运算符则使用stack.popd出最上面的两个数字,运算之后将结果压栈。持续往复,直到读取完表达式,此时栈内剩余的最后一个数值,即为后缀表达式的运算结果。

//后缀表达式计算结果
public void Calculate() {
    Stack stack = new Stack<>();
    for(int i = 0; i < suffix.size(); i++){
        String item = suffix.get(i);

        if(isNumeric(item)){
            //是数字
            stack.push(Double.parseDouble(item));
        }else {
            //是操作符,取出栈顶两个元素
            Double num2 = stack.pop();
            Double num1 = stack.pop();
            Double res = 0.0;
            if(item.equals("+")){
                res = num1 + num2;
            }else if(item.equals("-")){
                res = num1 - num2;
            }else if(item.equals("*")){
                res = num1 * num2;
            }else if(item.equals("/")){
                res = num1 / num2;
            }else if(item.equals("%")){
                res = num1 % num2;
            }else if(item.equals("^")){
                res = Math.pow(num1,num2);
            }
            System.out.println(num1 + " " +num2+ " " + item + " " + res);
            stack.push(res);
        }
    }
    area.append("n表达式结果为:"+stack.pop()+"n");
}
3、GUI实现计算器

实图如下,有些尺寸大小可以按照自己的喜好改。

代码如下:

public class Calculator{
    ArrayList expression = new ArrayList<>();//存储每轮输入字符
    String[] Operator = new String[]{"+","-","*","/","%","^","(",".",")"};//运算符集
    public static HashMap map = new HashMap<>();//运算符优先级
    public static ArrayList suffix = new ArrayList<>();//转为后缀表达式
    int bracket = 0;//前括号个数
    Jtextarea area;//显示屏
    public Calculator() {

    }
    public void createCalculator () {
        Jframe f = new Jframe("简版计算器");
        f.setBounds(400,200,300,360);
        f.setLayout(new FlowLayout(1,8,12));
        //显示屏
        area = new Jtextarea(4,24);
        area.setEditable(false);
        f.add(area);

        JPanel p = new JPanel();
        p.setLayout(new GridLayout(6,6,10,12));
        f.add(p);
        //按键
        JButton bracket1 = new JButton("(");p.add(bracket1);
        JButton bracket2 = new JButton(")");p.add(bracket2);
        JButton remainder = new JButton("%");p.add(remainder);
        JButton division = new JButton("/");p.add(division);
        JButton seven = new JButton("7");p.add(seven);
        JButton eight = new JButton("8");p.add(eight);
        JButton nine = new JButton("9");p.add(nine);
        JButton multiplication = new JButton("*");p.add(multiplication);
        JButton four = new JButton("4");p.add(four);
        JButton five = new JButton("5");p.add(five);
        JButton six = new JButton("6");p.add(six);
        JButton subtraction = new JButton("-");p.add(subtraction);
        JButton one = new JButton("1");p.add(one);
        JButton two = new JButton("2");p.add(two);
        JButton three = new JButton("3");p.add(three);
        JButton addition = new JButton("+");p.add(addition);
        JButton power = new JButton("^");p.add(power);
        JButton zero = new JButton("0");p.add(zero);
        JButton point = new JButton(".");p.add(point);
        JButton result = new JButton("=");p.add(result);

        JButton clear = new JButton("清屏");p.add(clear);
        f.setVisible(true);

        Priority();

        bracket1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(expression.size() == 0) {
                    expression.add("(");
                    area.append("(");
                    bracket++;
                    return;
                }else{
                    for(int i = 0; i < Operator.length; i++) {
                        if(expression.get(expression.size()-1).equals(Operator[i])) {
                            expression.add("(");
                            area.append("(");
                            bracket++;
                            return;
                        }
                    }
                    new MyDialog("数字之后不可以直接使用前括号!");
                }

            }
        });
        bracket2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(expression.size() == 0) {
                    new MyDialog("不可以直接使用后括号!");
                    return;
                }else{

                    for(int i = 0; i < Operator.length; i++) {
                        if(expression.get(expression.size()-1).equals(Operator[i])) {
                            new MyDialog("运算符后不可以使用后括号!");
                            return;
                        }
                    }
                }
                if(bracket > 0) {
                    expression.add(")");
                    area.append(")");
                    bracket--;
                }else{
                    new MyDialog("没有前括号与后括号对应~");
                }

            }
        });
        remainder.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageSymbol("%");
            }
        });
        division.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageSymbol("/");
            }
        });
        seven.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("7");
            }
        });
        eight.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("8");
            }
        });
        nine.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("9");
            }
        });
        multiplication.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageSymbol("*");
            }
        });
        four.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("4");
            }
        });
        five.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("5");
            }
        });
        six.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("6");
            }
        });
        subtraction.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageSymbol("-");
            }
        });
        one.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("1");
            }
        });
        two.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("2");
            }
        });
        three.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageNum("3");
            }
        });
        addition.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageSymbol("+");
            }
        });
        power.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StorageSymbol("^");
            }
        });
        zero.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(expression.get(expression.size()-1).equals("%") || expression.get(expression.size()-1).equals("/")) {
                    new MyDialog("分母不可以为零!");
                    return;
                }else{
                    StorageNum("0");
                }
            }
        });
        point.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(expression.size() == 0) {
                    new MyDialog("小数点使用不规范!");
                    return;
                }else{
                    if(isNumeric(expression.get(expression.size()-1)) == true) {
                        int serial = expression.size()-1;
                        String str = expression.get(serial);
                        if(str.charAt(str.length()-1) == '.') {
                            new MyDialog("小数点重复使用!");
                            return;
                        }else{
                            expression.set(serial,expression.get(serial) + ".");
                            area.append(".");
                        }
                        return;
                    }else{
                        new MyDialog("小数点使用不规范!");
                        return;
                    }
                }

            }
        });
        result.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 获取文本框的值
                area.append("=");
                evalRPN();
                Calculate();
            }
        });
        clear.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 获取文本框的值
                area.setText("");
                expression.clear();
                bracket = 0;
                suffix.clear();
            }
        });
    }
}

d窗的代码如下:

public class MyDialog {
    public MyDialog(String str) {
        Jframe dia = new Jframe();
        dia.setLayout(new FlowLayout(1,15,16));
        dia.setBounds(450,250,250,120);
        JLabel text = new JLabel(str);
        dia.add(text);
        JButton confirm = new JButton("确定");
        dia.add(/confirm/i);
        dia.setVisible(true);
        /confirm/i.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //内存中释放掉
                dia.dispose();
            }
        });
    }
}

4、新的体会

这次算是一次比较仓促的课设,一天激情敲代码搞完的项目,本身质量不算好,但基本 *** 作已经实现,也算是学到了一点点东西。这篇文章还有几个判断的函数没有放进去,想要代码的私信我。其实是很简单的东西,大家还是要动手敲代码,养成自己做项目的流程,效率会提高超多!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5672064.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存