实现的计算器界面如图,功能还算完善,输入一个公式后点击等号出结果。目前实现加减乘除和小括号,后续扩展其他运算原理类似。
递归去括号的思想
输入:555+(666-(222+333))*5
首先将整体视为在一个小括号:(555+(666-(222+333))*5)
寻找最里面的括号(222+333),计算结果并将结果替代括号单元:(555+(666-555)*5)
以此类推,寻找最里面括号,直到所有括号被数字替代。(递归函数的退出条件:只有一个数字)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class Main extends JFrame implements ActionListener{
private final static int N=20;
private JLabel outcome_lable=new JLabel("OutCome is:");//结果显示的标签
private JTextField input=new JTextField(50);//输入式子的文本框
private JTextArea display=new JTextArea(1,20);//输出结果的文本区
private JButton exit=new JButton("Exit");//退出按钮
private JButton help=new JButton("Help");//帮助按钮
private JPanel North_pan=new JPanel(); //面板容器,存放输入文本框、输出文本区等控件
private JPanel Center_pan=new JPanel(); //面板容器,存放其他控件
private JPanel Keypadpan=new JPanel(); //数字符号等按钮面板容器
private JButton Keypad[]; //定义一个按钮数组,存放各符号、数字等。
private String lable[]= //按钮上的标签
{"C","/","*","delete",
"7","8","9","-",
"4","5","6","+",
"1","2","3","=",
".","0","(",")"
};
private JPanel Center_Soupan=new JPanel();//用于存放帮助按钮、退出按钮的容器。
public Main(String title)
{
super(title);//命名
getContentPane().setLayout(new BorderLayout());//frame容器设置边界布局管理器
setkeypad();
North_pan.setLayout(new BorderLayout());//面板布局设置边界管理器,添加控件
North_pan.add(input,"North");
North_pan.add(display,"Center");
North_pan.add(outcome_lable,"West");
getContentPane().add(North_pan,"North");//面板容器添加到frame容器north区域
Center_pan.setLayout(new BorderLayout());//面板布局设置边界布局管理器,添加控件
Center_pan.add(Keypadpan,"Center");//keypadpan面板添加Center_pan面板
Center_Soupan.setLayout(new FlowLayout());//面板设置顺序布局管理器,添加控件
Center_Soupan.add(exit);
Center_Soupan.add(help);
Center_pan.add(Center_Soupan,"South");//Center_Soupan面板添加到Center_pan面板
getContentPane().add(Center_pan,"Center");//Center_pan面板容器添加到frame容器
display.setEditable(false);//输出文本区设置为只读
input.addActionListener(this);//输入框注册监听器
Keypad[15].addActionListener(this);//按键区各数字、符号按钮注册监听器
exit.addActionListener(this);//退出按钮注册监听器
help.addActionListener(this);//帮助按钮注册监听器
}
public void setkeypad() //生成键区
{
Keypadpan.setLayout(new GridLayout(5,4,1,1)); //设置格网布局管理器
Keypad=new JButton[N];
for(int k=0;k<Keypad.length;k++)
{
Keypad[k]=new JButton(lable[k]);
Keypad[k].addActionListener(this); //各按钮注册监听器
Keypadpan.add(Keypad[k]);
}
}
public void actionPerformed(ActionEvent e) //监听器接口事件处理方法
{
process_of_count haha=new process_of_count();
if(e.getSource()==exit)
{
System.exit(0);
}
else if(e.getSource()==help)
{
haha.dialog_show(); //调用dialog_show()函数,显示对话框
}
else if(e.getSource()==Keypad[0]){
input.setText(null); //选中C,则重置文本框内容
}
else if(e.getSource()==Keypad[3]){ //选中delete,则删除上一步字符
String str=input.getText();
String str1=str.substring(0, str.length()-1);
input.setText(str1);
}
else if(e.getSource()==Keypad[15]){ //选择=,则将文本框中的内容转化为字符数组,调用相关函数,进行相关运算
char[] a=input.getText().toCharArray();
String outcome=haha.do_count(a); //调用函数计算·结果
display.setText(outcome);
}
else {
JButton b=(JButton)e.getSource();
input.setText(input.getText()+b.getText());
}
}
public static void main(String[] args) {
Main f=new Main("calculator");
f.setSize(400, 300);
f.setVisible(true);
f.addWindowListener(new WindowAdapter(){
public void WindowClosing(WindowEvent e){
System.exit(0);
}
}); // TODO code application logic here
}
}
class process_of_count extends JFrame implements ActionListener{ //计算过程类
LinkedList<String> cai=new LinkedList<String>();
Dialog dlg=new Dialog(this);
Button Close_btn=new Button("conform");
JTextArea infor=new JTextArea("product:Calculator\nVersion:1.0\nAuthor:Cai Shuohao");
public void dialog_show(){ //帮助按下弹出对话框
dlg.setTitle("");
dlg.setLayout(new FlowLayout(FlowLayout.CENTER,5,30));
dlg.add(infor);
dlg.add(Close_btn);
infor.setEditable(false);
Close_btn.addActionListener(this);
dlg.setSize(100, 200);
dlg.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==Close_btn){
dlg.dispose();
}
}
public String do_count(char[] ch){ //将输入的公式(string)首先转化为了char数组,再进行计算
String a;
String str;
str="";
for(int i=0;i<ch.length;i++){
if(ch[i]=='.'||(int)ch[i]>=(int)'0'&&(int)ch[i]<=(int)'9'){
str=str+ch[i];
}
else{
if(!(str.equals(""))){
cai.add(str);
str="";}
String strr=String.valueOf(ch[i]);
cai.add(strr);
}
}
cai.add(str);
cai.addFirst("(");
cai.addLast(")");
try{ //如果表达式错误则抛出异常
a=remove_par(cai);
}catch(Exception e){
return "Error";
};
return a;
}
public String remove_par(LinkedList<String> ha){ //去括号计算函数(递归调用)
System.out.println();
int a1=0,a2=0;
LinkedList<String> hi=new LinkedList<String>();
for(int i=0;i<ha.size();i++){
if(ha.get(i).equals(")")){
for(int j=i-1;j>=0;j--){
if(ha.get(j).equals("(")){
a1=j;
a2=i;
break;
}
}
break;
}
}
if(a1!=0||a2!=0){
for(int k=a1+1;k<a2;k++){
hi.add(ha.get(k));
}
for(int i=0;i<hi.size();i++){
if(hi.get(i).equals("*")||hi.get(i).equals("/")){
if(hi.get(i).equals("*")){
double b=Double.parseDouble(hi.get(i+1));
double a=Double.parseDouble(hi.get(i-1));
double c=a*b;
hi.set(i-1, String.valueOf(c));
hi.remove(i+1);hi.remove(i);
i=0;
}
if(hi.get(i).equals("/")){
double b=Double.parseDouble(hi.get(i+1));
double a=Double.parseDouble(hi.get(i-1));
double c=a/b;
hi.set(i-1, String.valueOf(c));
hi.remove(i+1);hi.remove(i);
i=0;
}
}
}
for(int i=0;i<hi.size();i++){
if(hi.get(i).equals("+")||hi.get(i).equals("-")){
if(hi.get(i).equals("+")){
double b=Double.parseDouble(hi.get(i+1));
double a=Double.parseDouble(hi.get(i-1));
double c=a+b;
hi.set(i-1, String.valueOf(c));
hi.remove(i+1);hi.remove(i);
i=0;
}
if(hi.get(i).equals("-")){
double b=Double.parseDouble(hi.get(i+1));
double a=Double.parseDouble(hi.get(i-1));
double c=a-b;
hi.set(i-1, String.valueOf(c));
hi.remove(i+1);hi.remove(i);
i=0;
}
}
}
}
ha.set(a1, hi.getFirst());
for(int i=a2;i>=a1+1;i--){
ha.remove(i);
}
if(ha.size()!=1)
remove_par(ha); //回调自身
return ha.getFirst();
}
}