基于Java的计算器应用设计

一、准备阶段

1、学习frame.panel面板界面的设置

setVisible()可视化

setLayout 排版(Grid 水平 Border 东西南北 Flow 流式)

setSize() 大小

setBackground(Color)设置背景颜色
setBounds()设置坐标

pack自适应窗口

2、button按钮的设置

3、监听文本框

textField.addActionListener()

//需要对象

class MyActionListener1 implements ActionListener
        {


    @Override
    public void  actionPerformed(ActionEvent e) {
        TextField field =(TextField) e.getSource();//获取一些资源,返回一个对象
        System.out.println(field.getText());//获取输入框的文本
        field.setText("");
    }
}

4、运用java编写简单计算器进行双目运算

import java.util.Scanner;



public class Main {

    public static void main(String[] args) {



        Scanner input = new Scanner(System.in);

        int x = input.nextInt();

        int y = input.nextInt();

        char a = input.next().charAt(0);

        switch (a) {

            case '+':

                System.out.println(x + y);

                break;

            case '-':

                System.out.println(x - y);

                break;

            case '*':

                System.out.println(x * y);

                break;

            case '/':

                if (y == 0)

                    System.out.println("Divided by zero!");

                else

                System.out.println(x / y);

                break;

            default:

                System.out.println("Invalid operator!");

        }

    }

}

二、中缀表达式转后缀表达式:

(1)知识储备

1.中缀表达式要转后缀表达式,首先需要两个栈,其中一个应用于存放字符,另一个用于存放数字。

2.读到数字直接存入数字栈中,读到字符时,要与栈内前一元素进行比较,如果当前(要存入的字符)优先级大于前一字符时才存入,否则要将栈内元素弹出,并依次存入数字栈中。

3.遇到 ‘)'时将栈内所有字符依次弹出,并存入数字栈中,直到遇到 ‘(' 为止

4.当所有字符、数字访问完毕时,栈内很可能还会有剩余的字符,这是将他们一次弹出,并存入数字栈中

(2)算法实现
 

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;
}

三、后缀表达式的计算

(1)知识储备

后缀表达式的计算规则为:当遇到操作数(数字)时就将其入栈,当遇到操作符时就取出栈顶的两个元素,根据当前操作符进行计算,将计算结果再压入栈顶。如果表达式是规整的表达式,在整个表达式扫描完成之后栈顶将只有一个数字,该数据即为计算结果。

(2)算法实现
 

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 = "出错";
                        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];// 返回最终结果
    }

四、特殊运算的处理

增加了一些特殊的应用环境,使得计算器的功能更加完善,能够进行简单的特殊运算。

1、开方运算

public String kfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.sqrt(a);
        result = String.valueOf(b);//将运算结果转换为string类型并赋给string类型的变量result
        return result;
    }

2、平方运算

public String pfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.pow(a, 2);
        result = String.valueOf(b);
        return result;
    }

3、百分号运算

public String bfhys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = a / 100;
        result = String.valueOf(b);
        return result;
    }

五、源代码

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

import javax.swing.*;

public class Calculator extends JFrame implements ActionListener {
    private final String[] KEYS = {"√ ̄", "%", "x²", "AC", "e", "(", ")", "=", "7", "8", "9", "+", "4", "5", "6", "-", "1",
            "2", "3", "*", "π", "0", ".", "/"};
    private JButton keys[] = new JButton[KEYS.length];
    private JTextArea resultText = new JTextArea("0");// 文本域组件TextArea可容纳多行文本;文本框内容初始值设为0.0
    private JTextArea History = new JTextArea();// 历史记录文本框初始值设为空
    private JPanel jp2 = new JPanel();
    private JScrollPane gdt1 = new JScrollPane(resultText);//给输入显示屏文本域新建一个垂直滚动滑条
    private JScrollPane gdt2 = new JScrollPane(History);//给历史记录文本域新建一个垂直滚动滑条
    private JLabel label = new JLabel("历史记录");
    private String b = "";

    // 构造方法
    public Calculator() {
        super("Caculator");
        resultText.setBounds(20, 18, 255, 115);
        resultText.setAlignmentX(RIGHT_ALIGNMENT);
        resultText.setEditable(false);
        History.setBounds(290, 40, 250, 370);
        History.setAlignmentX(LEFT_ALIGNMENT);
        History.setEditable(false);
        label.setBounds(300, 15, 100, 20);
        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);
        History.setLineWrap(true);
        History.setWrapStyleWord(true);
        History.setSelectedTextColor(Color.blue);
        gdt2.setViewportView(History);
        gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        jp1.add(gdt1);
        jp2.add(gdt2);
        this.add(jp1);
        this.add(jp2);
        this.setLayout(null);
        this.add(label);// 新建“历史记录”标签

        // 放置按钮
        int x = 20, y = 150;
        for (int i = 0; i < KEYS.length; i++) {
            keys[i] = new JButton();
            keys[i].setBackground(Color.LIGHT_GRAY);
            keys[i].setText(KEYS[i]);
            keys[i].setBounds(x, y, 60, 40);
            if (x < 215) {
                x += 65;
            } else {
                x = 20;
                y += 45;
            }
            this.add(keys[i]);
        }
        for (int i = 0; i < KEYS.length; i++)
        {
            keys[i].addActionListener(this);
        }
        this.setResizable(false);
        this.setBounds(500, 200, 567, 480);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    // 事件处理
    public void actionPerformed(ActionEvent e) {
        String label = e.getActionCommand();
        if (Objects.equals(label, "="))
        {
            resultText.setText(this.b);
            History.setText(History.getText() + resultText.getText());
            if (label.equals("="))//调用计算方法,得出最终结果
            {
                String[] s = houzhui(this.b);
                String result = Result(s);
                this.b = result + "";
                resultText.setText(this.b);
                History.setText(History.getText()+"=" + resultText.getText()+"\n");
            }
        } else if (Objects.equals(label, "AC"))
        {
            this.b = "";
            resultText.setText("0");//更新文本域的显示,显示初始值;
        } else if (Objects.equals(label, "√ ̄")) {
            String n = kfys(this.b);
            resultText.setText("√"+this.b);
            this.b = n;
        } else if (Objects.equals(label, "x²")) {
            String m = pfys(this.b);
            resultText.setText(this.b + "^2" + "=" + m);
            this.b = m;
            History.setText(History.getText());
        } else if (Objects.equals(label, "%")) {
            String m = bfhys(this.b);
            this.b = m;
            resultText.setText(this.b);
            History.setText(History.getText());
        } else if (Objects.equals(label, "π") || Objects.equals(label, "e")) {
            if (label.equals("π")) {
                String m = String.valueOf(3.14159265);
                this.b = this.b + m;
                resultText.setText(this.b);
                History.setText(History.getText());
            } else if (label.equals("e")) {
                String m = String.valueOf(2.71828);
                this.b = this.b + m;
                resultText.setText(this.b);
                History.setText(History.getText());
            }
        } else {
            this.b = this.b + label;
            resultText.setText(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++)// 遍历中缀表达式
        {
            if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到数字字符的情况直接入队
            {
                s = "";// 作为承接字符,每次开始时都要清空
                for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {
                    s = s + str.charAt(i);
                }
                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 kfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.sqrt(a);
        result = String.valueOf(b);
        return result;
    }

    //平方运算方法
    public String pfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.pow(a, 2);
        result = String.valueOf(b);
        return result;
    }

    //百分号运算
    public String bfhys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = a / 100;
        result = String.valueOf(b);
        return result;
    }

    // 计算后缀表达式,并返回最终结果
    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]);
                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 = "出错";
                        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();
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值