- 学习或 Java Swing/Awt 创建交互友好的应用程序;
- 能通过界面按钮控件输入并实现算术表达式,输入的表达式即时在控件中显示,按下“=”按钮能实现运算,并将运算结果输出在控件中显示;要求能保存和浏览历史表达式的运算记录。
- 算术表达式求解,是指算术表达式中包括加、减、乘、除、括号等运算符,能求解包含括号的四则混合运算;并且能够检验表达式的合法性。
- 选做:①实现三角函数的运算、对数运算、指数运算、进制转换等;
②设计函数,分别求两个一元多项式的乘积与和。
首先先设计一个界面,并且设计一下按钮,确定每个地方应该放那个按钮
确定一下功能,实现按钮的监听,实现一下按钮的功能,当鼠标放在按钮上按下的时候,文本框内要出现这个按钮的文字。并且运算的结果也要能查看
运用双栈算符优先级法
求值的处理过程是自左至右扫描表达式的每一个字符:
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();
}
}
结果