栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

实验一 支持算术表达式求解的计算器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

实验一 支持算术表达式求解的计算器

一.项目概述

1.1项目目标和主要内容

1) 能通过设计的按钮控件输入并 实现算术 表达式 ,表达式 在文本框中 显示, 运算结果 输出显示; 保存和浏览历史运算记录;

2) 能够检验算术表达式的合法性;

3) 能够 实现混合运算 的求解 ,算术表达式中包括加、减、乘、除、括号等运算符 ;

4) 要求交互界面友好,程序健壮;

5)使用Java编程语言,在IntelliJ IDEA Community Edition上进行开发。

6)学习并实践JavaGUI编程和frame框架

求解两个一元多项式的乘积与和

•要求输入两个一元多项式的系数列表,输出结果多项式的系数列表。

•例如:

•1)3X4-5X2+6X-2

•2)  5X20-7X4+3X

•多项式和:  5X20-4X4-5X2+9X-2

•多项式的乘积:(a+b)(c+d)=ac+ad+bc+bd

•多项式乘积:15X24-25X22+30x21-10x20-21X8+35X6-33X5+14X4-15X3+18X2-6X

1.2项目的主要功能

基本的加,减,乘,除,四则运算   平方运算   开方运算   求余运算   历史记录

二.项目设计

      2.1项目总体框架

        算术表达式求值   :参与运算的数据(即操作数)可以为整数或实数,运算符(即操作符)

        为+、-、*、/(加、减、乘、除)等二元操作符,包括圆括号;如 :5*6+10-25=15    

        6+(5-4/2)*3=15

        运算规则:

       先乘除,后加减,从左到右计算,先括号内,后括号外;

      中缀表达式     A+(B-C/D)*E        

      后缀表达式     ABCD/-E*+    

三.程序运行结果及分析

运行效果:

分析

1、可实现基本四则运算及求余运算;

2、运算表达式可显示于输入界面并未实现保存历史记录栏;

3、输入界面和历史记录栏皆可实现不断字自动换行功能以及滚动条功能;

4、不足之处:尚未实现保存历史记录的功能无法退格

完整代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Objects;
import javax.swing.*;

class Calculator extends Jframe implements ActionListener {
    private final String[] KEYS = {"7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "*", "%", "/", "(", ")", ".", "="};
    private JButton keys[] = new JButton[KEYS.length];
    private Jtextarea resultText = new Jtextarea("0");// 文本域组件textarea可容纳多行文本;文本框内容初始值设为0.0
    private JPanel jp2 = new JPanel();
    private JScrollPane gdt1 = new JScrollPane(resultText);//给输入显示屏文本域新建一个垂直滚动滑条
    private String b = "";

    // 构造方法
    public Calculator() {
        super("宇宙无敌计算器");//“超”关键字,表示调用父类的构造函数,
        resultText.setBounds(20, 18, 255, 115);// 设置文本框大小
        resultText.setAlignmentX(RIGHT_ALIGNMENT);// 文本框内容右对齐
        resultText.setEditable(false);// 文本框不允许修改结果
        resultText.setBackground(Color.lightGray);
        jp2.setBounds(290, 40, 250, 370);//设置面板窗口位置及大小
        jp2.setLayout(new GridLayout());
        JPanel jp1 = new JPanel();
        jp1.setBounds(20, 18, 255, 115);//设置面板窗口位置及大小
        jp1.setLayout(new GridLayout());
        resultText.setLineWrap(true);// 激活自动换行功能
        resultText.setWrapStyleWord(true);// 激活断行不断字功能
        resultText.setSelectedTextColor(Color.RED);
        gdt1.setViewportView(resultText);//使滚动条显示出来
        gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条一直显示
        jp1.add(gdt1);//将滚动条添加入面板窗口中
        this.add(jp1);//将面板添加到总窗体中
        this.add(jp2);//将面板添加到总窗体中
        this.setLayout(null);
        // 放置按钮
        int x = 20, y = 150;
        for (int i = 0; i < KEYS.length; i++) {
            keys[i] = new JButton();
            keys[i].setText(KEYS[i]);
            keys[i].setBounds(x, y, 50, 40);
            keys[i].setBackground(Color.gray);
            if (x < 215) {
                x += 65;
            } else {
                x = 20;
                y += 53;
            }
            this.add(keys[i]);
        }
        for (int i = 0; i < KEYS.length; i++)// 每个按钮都注册事件监听器
        {
            keys[i].addActionListener(this);
        }
        this.setResizable(false);
        this.setBounds(500, 200, 300, 465);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
    }


    // 事件处理
    public void actionPerformed(ActionEvent e) {
        //History.setText(b);//使输入的表达式显示在历史记录文本框中
        String label = e.getActionCommand();//获得事件源的标签
        if (Objects.equals(label, "="))//
        {
            resultText.setText(this.b);
            if (label.equals("="))//调用计算方法,得出最终结果
            {
                String[] s = houzhui(this.b);
                String result = Result(s);
                this.b = result + "";
                //更新文本框,当前结果在字符串b中,并未删除,下一次输入接着此结果以实现连续运算
                resultText.setText(this.b);
            }
        } else if (Objects.equals(label, "AC"))//清空按钮,消除显示屏文本框前面所有的输入和结果
        {
            this.b = "";
            resultText.setText("0");//更新文本域的显示,显示初始值;
        } else {
            this.b = this.b + label;
            resultText.setText(this.b);
            // History.setText(History.getText()+this.b);
        }
        //History.setText(History.getText()+this.b);//使输入的表达式显示在历史记录文本框中
    }

    //将中缀表达式转换为后缀表达式
    private String[] houzhui(String str) {
        String s = "";// 用于承接多位数的字符串
        char[] opStack = new char[100];// 静态栈,对用户输入的操作符进行处理,用于存储运算符
        String[] postQueue = new String[100];// 后缀表达式字符串数组,为了将多位数存储为独立的字符串
        int top = -1, j = 0;// 静态指针top,控制变量j
        for (int i = 0; i < str.length(); i++)// 遍历中缀表达式
        // indexof函数,返回字串首次出现的位置;charAt函数返回index位置处的字符;
        {
            if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到数字字符的情况直接入队
            {
                s = "";// 作为承接字符,每次开始时都要清空
                for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {
                    s = s + str.charAt(i);
                    //比如,中缀表达式:234+4*2,我们扫描这个字符串的时候,s的作用相当于用来存储长度为3个字符的操作数:234
                }
                i--;
                postQueue[j] = s;// 数字字符直接加入后缀表达式
                j++;
            } else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括号
                top++;
                opStack[top] = str.charAt(i);// 左括号入栈
            } else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括号
                for (; ; )// 栈顶元素循环出栈,直到遇到左括号为止
                {
                    if (opStack[top] != '(') {// 栈顶元素不是左括号
                        postQueue[j] = opStack[top] + "";// 栈顶元素出栈
                        j++;
                        top--;
                    } else { // 找到栈顶元素是左括号
                        top--;// 删除栈顶左括号
                        break;// 循环结束
                    }
                }
            } else if ("*%/+-".indexOf(str.charAt(i)) >= 0)// 遇到运算符
            {
                if (top == -1) {// 若栈为空则直接入栈
                    top++;
                    opStack[top] = str.charAt(i);
                } else if ("*%/".indexOf(opStack[top]) >= 0) {// 当栈顶元素为高优先级运算符时,让栈顶元素出栈进入后缀表达式后,当前运算符再入栈
                    postQueue[j] = opStack[top] + "";
                    j++;
                    opStack[top] = str.charAt(i);
                } else {
                    top++;
                    opStack[top] = str.charAt(i);// 当前元素入栈
                }
            }
        }
        while (top != -1) {// 遍历结束后将栈中剩余元素依次出栈进入后缀表达式
            postQueue[j] = opStack[top] + "";
            j++;
            top--;
        }
        return postQueue;
    }

    // 计算后缀表达式,并返回最终结果
    public String Result(String[] str) {
        String[] Result = new String[100];// 顺序存储的栈,数据类型为字符串
        int Top = -1;// 静态指针Top
        for (int i = 0; str[i] != null; i++) {
            if ("+-*%/".indexOf(str[i]) < 0) {  //遇到数字,直接入栈
                Top++;
                Result[Top] = str[i];
            }
            if ("+-*%/".indexOf(str[i]) >= 0)// 遇到运算符字符,将栈顶两个元素出栈计算并将结果返回栈顶
            {
                double x, y, n;
                x = Double.parseDouble(Result[Top]);// 顺序出栈两个数字字符串,并转换为double类型
                Top--;
                y = Double.parseDouble(Result[Top]);
                Top--;
                if ("*".indexOf(str[i]) >= 0) {
                    n = y * x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈

                }
                if ("/".indexOf(str[i]) >= 0) {
                    if (x == 0)// 被除数不允许为0
                    {
                        String s = "error!";
                        return s;
                    } else {
                        n = y / x;
                        Top++;
                        Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                    }
                }
                if ("%".indexOf(str[i]) >= 0) {
                    if (x == 0)// 被除数不允许为0
                    {
                        String s = "error!";
                        return s;
                    } else {
                        n = y % x;
                        Top++;
                        Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                    }
                }
                if ("-".indexOf(str[i]) >= 0) {
                    n = y - x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                }
                if ("+".indexOf(str[i]) >= 0) {
                    n = y + x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                }
            }
        }
        return Result[Top];// 返回最终结果
    }

    // 主函数
    public static void main(String[] args) {

        Calculator a = new Calculator();
    }
}

四.总结

4.1项目的难点和关键点

中缀表达式与后缀表达式的运算实现,算法思想

4.2项目的评价

计算器的主要功能可以实现,未能实现历史记录保存

4.3心得体会

通过这个项目,我学习了GUI的图形界面设计,设计期间出现了各种问题,还有许多方面需要学习

5.参考文献

CSDN官网  Java编写简单计算器--实现篇 @阿雪狼

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/658315.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号