实验一 简单计算器的实现

  1. 学习或 Java Swing/Awt 创建交互友好的应用程序;
  2. 能通过界面按钮控件输入并实现算术表达式,输入的表达式即时在控件中显示,按下“=”按钮能实现运算,并将运算结果输出在控件中显示;要求能保存和浏览历史表达式的运算记录。
  3. 算术表达式求解,是指算术表达式中包括加、减、乘、除、括号等运算符,能求解包含括号的四则混合运算;并且能够检验表达式的合法性。
  4. 选做:①实现三角函数的运算、对数运算、指数运算、进制转换等;

      ②设计函数,分别求两个一元多项式的乘积与和。

首先先设计一个界面,并且设计一下按钮,确定每个地方应该放那个按钮

确定一下功能,实现按钮的监听,实现一下按钮的功能,当鼠标放在按钮上按下的时候,文本框内要出现这个按钮的文字。并且运算的结果也要能查看

运用双栈算符优先级法

求值的处理过程是自左至右扫描表达式的每一个字符:

       1、当扫描到的是运算数,则将其压入栈OPND

       2、当扫描到的是运算符时:

            如这个运算符比OP栈顶运算符的优先级高,则入栈;

            如这个运算符比OP栈顶运算符优先级低,则从OPND栈中弹出两个运算符,从栈OP中弹出栈顶运算符进行运算,并将运算结果压入栈OPND。

       3、继续处理当前字符,直到遇到结束符为止。

package jsq;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
public class Log {
    public void writeFile(String expression, String result) {
        try {
            final String currentLogPath = System.getProperty("user.dir");
            final String fileName = currentLogPath + "/log.txt";

            FileWriter writer = new FileWriter(fileName, true);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = sdf.format(new java.util.Date());

            writer.write(time + ": " + expression + " = " + result + "\n");
            writer.close();
        } catch (IOException e) {
            System.out.println("Problem writing file!!!");
        }

    }
}
package jsq;
import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
public class Main {
    public static void main(String[] args) throws MalformedURLException {
        final int width = 400;
        final int height = 500;



        BuildUI calculator = new BuildUI();
        calculator.buildLayout();
        calculator.setSize(width, height);
        calculator.setVisible(true);
    }
}
package jsq;
import java.util.LinkedList;
public class ResultBuffer {
    final int maxBufferLength = 10;
    int currentBufferLength = 0;
    int pointer = -1;

    LinkedList<String> buffer = new LinkedList<>();

    public void addElement(String ele) {
        buffer.addFirst(ele);
        if (currentBufferLength < maxBufferLength) {
            currentBufferLength++;
        } else {
            buffer.removeLast();
        }
    }

    public String getElement() {
        return buffer.get(pointer);
    }

    public void increasePointer() {
        pointer = (pointer + 1) % currentBufferLength;
    }

    public void resetPointer() {
        pointer = 0;
    }
}
package jsq;
import java.math.BigDecimal;
import java.util.LinkedList;
class InputException extends Exception {
    InputException() {
        super();
    }
}


public class Calculate {
    public String evaluationExpression(String expression) throws InputException {
        /* operator in the stack */
        LinkedList<Character> stackOptr = new LinkedList<>();
        /* operand in the stack */
        LinkedList<Double> stackOpnd = new LinkedList<>();
        /* add '@' to the bottom of the stack*/
        stackOptr.addFirst('@');
       int i = 0;
        while (i < expression.length()) {
            if ('0' <= expression.charAt(i) && '9' >= expression.charAt(i)) {
                double number;
                double integerPart = 0, decimalPart = 0;
                boolean beforeDecimalPoint = true;
                int decimalRank = 10;

                while (('0' <= expression.charAt(i) && '9' >= expression.charAt(i)) || '.' == expression.charAt(i)) {

                    if ('.' == expression.charAt(i)) {
                        if (beforeDecimalPoint) {
                            beforeDecimalPoint = false;
                            i++;
                        } else {
                            throw new InputException();
                        }
                    }

                    if (beforeDecimalPoint) {
                        integerPart = integerPart * 10 + (expression.charAt(i) - '0');
                    } else {
                        decimalPart = decimalPart + (double) (expression.charAt(i) - '0') / decimalRank;
                        decimalRank *= 10;
                    }

                    i++;

                    if ('c' == expression.charAt(i) || 's' == expression.charAt(i) || '(' == expression.charAt(i)) {
                        throw new InputException();
                    }
                }
                number = integerPart + decimalPart;
                stackOpnd.addFirst(number);
            } else {
                switch (precede(stackOptr.getFirst(), expression.charAt(i))) {
                    case '<':
                        stackOptr.addFirst(expression.charAt(i));
                        break;
                    case '=':
                        stackOptr.removeFirst();
                        break;
                    case '>':
                        if ('c' == stackOptr.getFirst()) {
                            double a = stackOpnd.removeFirst();
                            stackOpnd.addFirst(Math.cos(a));
                        } else if ('s' == stackOptr.getFirst()) {
                            double a = stackOpnd.removeFirst();
                            stackOpnd.addFirst(Math.sin(a));
                        } else {
                            double a = stackOpnd.removeFirst();
                            double b = stackOpnd.removeFirst();
                            stackOpnd.addFirst(operate(a, stackOptr.getFirst(), b));
                        }
                        i--;
                        stackOptr.removeFirst();
                        break;
                }
                if ('s' == expression.charAt(i) || 'c' == expression.charAt(i)) {
                    i += 3;
                } else {
                    i++;
                }
            }
        }

        return String.valueOf(stackOpnd.getFirst());
    }


    public char precede(char ch1, char ch2) {
        int a = 0, b = 0;

        switch (ch1) {
            case '+':
                a = 5;
                break;
            case '-':
                a = 5;
                break;
            case '*':
                a = 15;
                break;
            case '/':
                a = 15;
                break;
            case '(':
                a = 2;
                break;
            case ')':
                a = 25;
                break;
            case '^':
                a = 17;
                break;
            case '#':
                a = 0;
                break;
            case 's':
                a = 20;
                break;
            case 'c':
                a = 20;
                break;
            case '@':
                a = 0;
                break;
        }

        switch (ch2) {
            case '+':
                b = 3;
                break;
            case '-':
                b = 3;
                break;
            case '*':
                b = 10;
                break;
            case '/':
                b = 10;
                break;
            case '(':
                b = 22;
                break;
            case ')':
                b = 2;
                break;
            case '^':
                b = 16;
                break;
            case 's':
                b = 19;
                break;
            case 'c':
                b = 19;
                break;
            case '#':
                b = 0;
                break;
            case '@':
                b = 0;
                break;
        }

        if (a > b)
            return '>';
        else if (a == b)
            return '=';
        else
            return '<';

    }

    double operate(double a, char sign, double b) {
        BigDecimal aa = BigDecimal.valueOf(a);
        BigDecimal bb = BigDecimal.valueOf(b);

        BigDecimal answer = null;

        switch (sign) {
            case '+':
//                        answer = b + a;
                answer = bb.add(aa);
                break;
            case '-':
//                        answer = b - a;
                answer = bb.subtract(aa);
                break;
            case '*':
//                        answer = b * a;
                answer = bb.multiply(aa);
                break;
            case '/':
//                        answer = b / a;
                answer = bb.divide(aa);
                break;
            case '^':
//                        answer = Math.pow(b, a);
                answer = bb.pow(aa.intValue());
                break;
            default:

                break;
        }

        System.out.println(answer);

        return answer.doubleValue();
    }
}
package jsq;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Display {
    private final String[] keys = {
            "AC", "(", ")", "x",
            "7", "8", "9", "+",
            "4", "5", "6", "-",
            "1", "2", "3", "*",
            "0", ".", "=", "/",
            "", "", "", "<--"};
    private final JTextField result = new JTextField();
    private final JButton[] button = new JButton[keys.length];

    public Display() {
        /* initialize the text box */
        result.setText("0");
        result.setCaretColor(Color.white);
        /* text color */
        result.setForeground(Color.white);
        /* background color */
        result.setBackground(Color.black);
    }

    public void setResult(String str) {
        /* set number in the text box */
        result.setText(str);
    }

    public JTextField getResult() {
        /* get numbers from text box */
        return result;
    }

    public JButton[] getButton() {
        return button;
    }

    public void setButton(JButton button, int i) {
        this.button[i] = button;
    }

    public String getKey(int i) {
        return keys[i];
    }
}

class BuildUI extends JFrame implements ActionListener {
    Display dis = new Display();
    String expression;
    final Font resultFont = new Font("Helvetica", Font.PLAIN, 60);
    final Font buttonFont = new Font("Helvetica", Font.PLAIN, 30);
    ResultBuffer rb = new ResultBuffer();

    public void buildLayout() {
        JPanel calFrame = new JPanel();
        calFrame.setBackground(Color.black);

        /* seven rows, four cols */
        calFrame.setLayout(new GridLayout(7, 1));
        calFrame.add(dis.getResult());
        dis.getResult().setFont(resultFont);
        Container[] con = new Container[6];

        /* set each key */
        for (int i = 0; i < con.length; i++) {
            con[i] = new Container();
            con[i].setLayout(new GridLayout(1, 4));
            calFrame.add(con[i]);
        }

        for (int i = 0; i < dis.getButton().length; i++) {
            JButton newButton = setBtnForm(i);
//                        newButton.setForeground(Color.DARK_GRAY);

            dis.setButton(newButton, i);
            con[i / 4].add(newButton);
        }

        getContentPane().add(calFrame);
        expression = "";
    }

    public JButton setBtnForm(int i) {
        /* set font, color, shape of the buttom */
        JButton newButton = new JButton(dis.getKey(i));
        newButton.setBorderPainted(true);
        if (0 == i || 1 == i || 2 == i) {
            newButton.setForeground(Color.black);
            newButton.setBackground(Color.lightGray);
//                        Image icon = getDefaultToolkit().getImage("/Users/fengfeitong/IdeaProjects/Calculator/IMG_4018.jpg");
//                        newButton.setIconImage(icon);
        } else if (0 == (i + 1) % 4) {
            newButton.setForeground(Color.black);
            newButton.setBackground(Color.orange);
        } else {
            newButton.setForeground(Color.black);
            newButton.setBackground(Color.darkGray);
        }

        newButton.addActionListener(this);
        newButton.setFont(buttonFont);

        return newButton;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String action = e.getActionCommand();

        if (dis.getKey(0).equals(action)) {
            /* press AC */
            pressAC();
        } else if (dis.getKey(3).equals(action)) {
            /* press Delete */
            pressDelete();
        } else if (dis.getKey(18).equals(action)) {
            /* press = */
            pressCalculate();
        } else if (dis.getKey(23).equals(action)) {
            /* press <-- */
            pressResultBuffer();
        } else {
            /* press 1, 2, 3, +, - ...*/
            pressExpression(action);
        }

    }

    public void pressAC() {
        /* clear the text box */
        expression = "";
        dis.setResult("0");
        rb.resetPointer();
    }

    public void pressDelete() {
        /* delete the last character in the text box */
        expression = expression.substring(0, expression.length() - 1);
        dis.setResult(expression);
        rb.resetPointer();
    }

    public void pressCalculate() {
        /* compute */
        Calculate cal = new Calculate();

        try {
            String re = cal.evaluationExpression(expression + '@');
            dis.setResult(re);
            rb.addElement(expression + " = "  + re);

            Log l = new Log();
            l.writeFile(expression, re);
        } catch (Exception e) {
            dis.setResult("INPUT ERROR!!!");
        }
        expression = "";
        rb.resetPointer();
    }

    public void pressExpression(String action) {
        /* input... */
        expression += action;
        dis.setResult(expression);
        rb.resetPointer();
    }

    public void pressResultBuffer() {
        dis.setResult(rb.getElement());
        rb.increasePointer();
    }
}

 结果

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值