package data_structures.Project1;
import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.JFileChooser; //用来创建文件选择器
import javax.swing.JPanel; //中间容器 (嵌板)最常用的面板
import javax.swing.JButton; //按钮,以单击按钮的响应来打开文件选择器
import java.awt.event.ActionEvent; //响应按钮的动作事件类
import java.awt.event.ActionListener;
public class CalculatorPanel extends JPanel {
private JButton display;
private JButton display_2;
private JPanel panel;
private boolean start;
public CalculatorPanel() {
setLayout(new BorderLayout());
start = true;
display = new JButton("0");
Font Fonts = new Font("行书", Font.BOLD, 30);
display.setFont(Fonts);
display.setEnabled(false);
add(display, BorderLayout.NORTH);
display.setPreferredSize(new Dimension(150,100));
display_2 = new JButton("0");
display_2.setFont(Fonts);
display_2.setEnabled(false);
add(display_2, BorderLayout.SOUTH);
display_2.setPreferredSize(new Dimension(150,80));
ActionListener insert = new InsertAction();
ActionListener command = new CommandAction();
ActionListener openFile = new OpenFileAction();
// add the buttons
panel = new JPanel();
panel.setLayout(new GridLayout(3, 6));
addButton_number("7", insert);
addButton_number("8", insert);
addButton_number("9", insert);
addButton_sp(panel, openFile);
addButton("/", insert);
addButton("*", insert);
addButton_number("4", insert);
addButton_number("5", insert);
addButton_number("6", insert);
addButton_number("0", insert);
addButton("-", insert);
addButton("+", insert);
addButton_number("1", insert);
addButton_number("2", insert);
addButton_number("3", insert);
addButton("=", command);
addButton("(",insert);
addButton(")",insert);
add(panel, BorderLayout.CENTER);
}
private void addButton(String label, ActionListener listener) {
JButton button = new JButton(label);
button.addActionListener(listener);
panel.add(button);
button.setPreferredSize(new Dimension(30,30));
button.setBackground(Color.lightGray);
Font Fonts = new Font("行书", Font.BOLD, 30);
button.setFont(Fonts);
}
private void addButton_number(String label, ActionListener listener) {
JButton button = new JButton(label);
button.addActionListener(listener);
panel.add(button);
button.setPreferredSize(new Dimension(30,30));
Font Fonts = new Font("行书", Font.BOLD, 30);
button.setFont(Fonts);
}
private void addButton_sp(JPanel panel, ActionListener listener) {
JButton button = new JButton("file"); //按钮,单击响应事件,打开文件选择器
panel.add(button);
button.setPreferredSize(new Dimension(30,30));
button.setBackground(Color.pink);
Font Fonts = new Font("行书", Font.BOLD, 30);
button.setFont(Fonts);
button.addActionListener(listener);
}
private class InsertAction implements ActionListener {
public void actionPerformed(ActionEvent event) {
String input = event.getActionCommand();
if (start) {
display.setText("");
start = false;
}
if (isInteger(input)||input.equals(".")){
display.setText(display.getText() + input);
}else {
display.setText(display.getText() + " " + input + " ");
}
}
}
private class CommandAction implements ActionListener {
public void actionPerformed(ActionEvent event) {
calculate(display.getText());
start = true;
}
}
private class OpenFileAction implements ActionListener {
public void actionPerformed(ActionEvent event) {
String s = "";
String path;
JFileChooser jf = new JFileChooser("D:\\"); //文件选择器,设置初始路径为"F:\\"
jf.showOpenDialog(null);
path = jf.getSelectedFile().getPath();
int ret =jf.showOpenDialog(null); //选择文件,选择路径
if (ret == JFileChooser.APPROVE_OPTION) {
path = jf.getSelectedFile().getPath();
}
System.out.println(path);
File op = new File(path);
s = readFile(op);
display.setText(s);
start = true;
}
}
static public String readFile(File file) {
try {
FileInputStream fileInputStream = new FileInputStream(file);
// 把每次读取的内容写入到内存中,然后从内存中获取
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
// 只要没读完,不断的读取
while ((len = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
// 得到内存中写入的所有数据
byte[] data = outputStream.toByteArray();
fileInputStream.close();
return new String(data);
//return new String(data, "GBK");//以GBK(什么编码格式)方式转
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public String[] getExpression(String displays){
return displays.trim().split("\\s+"); //重要
}
public java.util.List change_in_to_suf(String displays){
String[] inExpression = getExpression(displays);
stack s1 = new stack(100); //运算符栈
java.util.List<String> s2 = new ArrayList<>();//中间结果栈
for (String s : inExpression) {
if (isOperator(s)) { //是否是运算符
if (!s1.isEmpty() && !priority(s,s1.peek()) && !s1.peek().equals("(")) {
while (!s1.isEmpty() && !s1.peek().equals("(")) {
s2.add(s1.pop());
}
}
s1.push(s);
} else if (isNumber(s)) { //不是运算符判断是否是数字
s2.add(s);
} else if (s.equals("(")) { //不是运算符和数字看是否是左括号
s1.push(s);
} else if (s.equals(")")) { //不是运算符和数字和左括号看是不是右括号
while (!s1.isEmpty()) { //运算符栈不为空时
if (s1.peek().equals("(")) {
s1.pop();
break;
} else {
s2.add(s1.pop());
}
}
} else {
throw new RuntimeException("非法字符");
}
}
while (!s1.isEmpty()) {
s2.add(s1.pop());
}
return s2;
}
public void calculate(String displays){
List s = change_in_to_suf(displays);
StringBuilder total= new StringBuilder();
for (Object o : s) {
total.append(o);
display_2.setText("The suffix expression: " + total);
}
stack s0 = new stack(100);
int res = 0;
for (Object o : s) {
if (isNumber((String) o)) {
s0.push((String) o);
} else if (s0.top > 0) {
int num2 = Integer.parseInt(s0.pop());
int num1 = Integer.parseInt(s0.pop());
switch ((String) o) {
case "+":
res = num1 + num2;
break;
case "-":
res = num1 - num2;
break;
case "*":
res = num1 * num2;
break;
case "/":
res = num1 / num2;
break;
}
s0.push(String.valueOf(res));
}
}
String result = s0.pop();
display.setText("result" + "= "+ result);
}
public boolean isNumber(String str){
for (int i=0; i<str.length(); i++){
if (!Character.isDigit(str.charAt(i))){
return false;
}
}
return true;
}
public static boolean isOperator(String op){
return op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/");
}
public static boolean isInteger(String str) {
Pattern pattern = Pattern.compile("[0-9]");
return pattern.matcher(str).matches();
}
public static boolean priority(String op, String next) {
if (priority_s(op)==1) {
return true;
} else return priority_s(next) != 1;
}
public static int priority_s(String op){
if (op.equals("*")||op.equals("/")){
return 1;
}else {
return 0;
}
}
}
stack.java
package data_structures.Project1;
public class stack {
public int maxSize;
public String[] stack;
public int top = -1;
public stack(int maxSize) {
this.maxSize=maxSize;
stack = new String[this.maxSize];
}
//栈满
public boolean isFull() {
return top == maxSize -1;
}
//栈空
public boolean isEmpty() {
return top == -1;
}
//入栈
public void push(String value) {
if(isFull()) {
System.out.println("栈满");
}
top++;
stack[top] =value;
}
//出栈
public String pop() {
if(isEmpty()) {
throw new RuntimeException("栈空");
}
String value = stack[top];
top--;
return value;
}
public int getSize() {
int size = 0;
if(isEmpty()) {
System.out.println("栈空,没有数据");
return size;
}
for(int i = top;i>=0;i--) {
size++;
}
return size;
}
public String peek(){
return stack[top];
}
}
CalculatorFrame.java
package data_structures.Project1;
import javax.swing.*;
public class CalculatorFrame extends JFrame {
public CalculatorFrame() {
add(new CalculatorPanel());
pack();
}
}
Calculator.java
package data_structures.Project1;
//利用栈完成算术表达式求值:从键盘或文件中输入算术表达式,计算其结果并显示。要求采用 2 种处理过程实现:
// (1)转换为后缀表达式并输出,然后对后缀表达式求值并输出;
// (2)不需要显式转换为后缀表达式,直接输出求值结果。
// 输入的表达式中可以有整数、实数、括号,运算符至少包括+、-、*、/、单目负。
// 要求具有友好的用户界面(不推荐使用命令行方式),可以多次输入不同的表达式进行计算,
// 直到用户选择“退出”。
// 栈的基本操作自己实现,不允许使用系统提供的 STL 实现
import java.awt.*;
import javax.swing.*;
public class Calculator {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
CalculatorFrame frame = new CalculatorFrame();
frame.setTitle("The Best Calculator");
frame.setSize(600,450);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}