我加过了限制条件,
因为随手写的,所以这个显得很凌乱,这样的编码风格很不好,回来我再把代码整理下。
import java.awt.*;
import javax.swing.*;import java.awt.event.*;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Test33 extends JFrame implements ActionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
JPanel jp1,jp2;
String Button_str[]={"1","2","3","C","4","5","6","B","7","8","9","+","0",".","=","-","*","/","(",")"};
JButton button[]=new JButton[Button_str.length];
//JButton jb0,jb1,jb2,jb3,jb4,jb5,jb6,jb7,jb8,jb9,jbadd,jbplus,jbcheng,jbchu,jbdian,jbdeng;
JTextField jtf;
boolean isequaled=false;
int leftP=0,rightP=0; //计算左右括号数量
Double result =0.0;//存储运算结果
public static void main(String[] args) {
Test33 frame=new Test33();
frame.setTitle("计算器");
frame.setSize(400,300);
//frame.pack();
frame.setLocation(100,100);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
public Test33(){
jp1=new JPanel(new GridLayout(5,4));
for(int i=0;i<Button_str.length;i++){
button[i]=new JButton(Button_str[i]);
jp1.add(button[i]);
button[i].addActionListener(this);
}
jtf=new JTextField(26);
jtf.setText("0");
jtf.setBackground(Color.white);
jtf.setEditable(false);
jp2=new JPanel();
jp2.add(jtf);
this.add(jp2,BorderLayout.NORTH);
this.add(jp1);
}
@Override
public void actionPerformed(ActionEvent e) {
String buttonLable=e.getActionCommand();//得到事件源对象的标签
if(buttonLable.equals("C"))//如果按C则清除jtf
{
jtf.setText("0");
}
else if(buttonLable.equals("B"))//如果按B则jtf中的数据删除最后一个
{
jtf.setText(jtf.getText().substring(0,jtf.getText().length()-1));
}
else //按正常处理
{
if(buttonLable.equals("("))
{
leftP++;
}else if(buttonLable.equals(")"))
{
rightP++;
}
if(isequaled)//如果按过等号则再按数字则自动还原初始状态
{
isequaled=false;
if(buttonLable.matches("\\*|\\+|\\-|/"))
{
jtf.setText(result+buttonLable);
}else if(buttonLable.matches("\\."))
{
jtf.setText("0"+buttonLable);
}else
{
jtf.setText(buttonLable);
}
}
else
{
if((jtf.getText().equals("0")&&!buttonLable.matches("\\*|\\+|\\-|/|\\."))||jtf.getText().equals("左右括号不等!"))//如果一开始按非符号则代替原文本
{
jtf.setText(buttonLable);
}
else if(String.valueOf(jtf.getText().charAt(jtf.getText().length()-1)).matches("\\*|\\+|\\-|/||\\(")&&buttonLable.matches("\\*|\\+|\\-|/|\\)") )
{
;//若按两次运算符号则无用
}
else
{
jtf.setText(jtf.getText()+buttonLable);
}
}
if(buttonLable.equals("="))
{
isequaled=true;//表示按过等号
if(leftP!=rightP)
{
jtf.setText("左右括号不等!");
leftP=0;//左右括号归0
rightP=0;//左右括号归0
}else
{
if(String.valueOf(jtf.getText().charAt(jtf.getText().length()-2)).matches("\\*|\\+|\\-|/"))//若计算器以运算符结尾
{
jtf.setText(jtf.getText().substring(0,jtf.getText().length()-2)+buttonLable);
}
try {
result=calculatorCore(jtf.getText().substring(0,jtf.getText().length()-1) +"#");
jtf.setText(jtf.getText()+result);
leftP=0;//左右括号归0
rightP=0;//左右括号归0
}
catch(Exception exc)
{
jtf.setText("错误,被除数不能为0!");
}
}
}
}
}
Double calculatorCore(String exp) throws Exception
{
//首先把表达式转化成后缀表达式
Stack<String> operator=new Stack<String>();
Queue<String> operatand=new LinkedList<String>();
Stack<Double> result=new Stack<Double>();
int j=0;
while(exp.charAt(j)!='#')
{
if(String.valueOf(exp.charAt(j)).matches("[0-9]|\\."))
{
String temp="";
//如果String中j的位置为数字,则依次检测其后面位置,若都是数字,则把这些数字合并成一个数,存在operatand队列中
while(String.valueOf(exp.charAt(j)).matches("[0-9]|\\."))
{
temp+=String.valueOf(exp.charAt(j));
j++;
}
operatand.offer(temp);
}
//如果String中j的位置为+或-则若operator栈空,+或-入栈,若非空则将里面'('之前的操作符依次出栈(若‘(’存在),再依次放入operatand队列中,+或-再入栈
//因为+,-优先级最低
if(exp.charAt(j)=='+'||exp.charAt(j)=='-')
{
if(!operator.empty())
{
while(!operator.empty()&&!operator.peek().equals("("))
{
operatand.offer(operator.pop());
}
operator.push(String.valueOf(exp.charAt(j)));
}
else
{
operator.push(String.valueOf(exp.charAt(j)));
}
j++;
}
/*如果String中j的位置为*或/则若operator栈空,*或/入栈,若非空则循环判断栈顶元素若栈顶元素为*或/则栈顶元素出栈,入operatand队
直至栈顶元素为+或-和‘(’,或者为空时*/
//因为*,/优先级最高
if(exp.charAt(j)=='*'||exp.charAt(j)=='/')
{
if(!operator.empty())
{
while(!operator.empty()&&!operator.peek().equals("(")&&!operator.peek().equals("+")&&!operator.peek().equals("-"))
{
while(operator.peek().equals("*")||!operator.peek().equals("/"))
{
operatand.offer(operator.pop());
}
}
operator.push(String.valueOf(exp.charAt(j)));
}
else
{
operator.push(String.valueOf(exp.charAt(j)));
}
j++;
}
/*如果String中j的位置为"("则直接入operator栈 */
if(exp.charAt(j)=='(')
{
operator.push(String.valueOf(exp.charAt(j)));
j++;
}
/*如果String中j的位置为")"则operator栈'('之前的操作符依次出栈,入opertand队列,“(”舍去,“)”出栈舍去 */
if(exp.charAt(j)==')')
{
while(!operator.peek().equals("("))
{
operatand.offer(operator.pop());
}
operator.pop(); //"("出栈
j++;
}
}
//此时operator栈一定非空,将其内操作符依次出栈,入operatand队
int count=operator.size();
for(int i=0;i<count;i++)
{
operatand.offer(operator.pop());
}
/*
*到此为止operatand队列内为原表达式的逆波兰式
*下面将计算逆波兰式
*/
while(operatand.peek()!=null)
{
if(operatand.peek().matches("^[0-9]*$|^[0-9]*\\.[0-9]*$"))
{
result.push(Double.parseDouble(operatand.poll()));
}
else if(operatand.peek().equals("+"))
{
BigDecimal addendo = new BigDecimal(result.pop().toString());
BigDecimal addendt = new BigDecimal(result.pop().toString());
result.push(addendo.add(addendt).doubleValue());
operatand.poll();
}
else if(operatand.peek().equals("-"))
{
BigDecimal meiosis = new BigDecimal(result.pop().toString());//先取出减数
BigDecimal minuend = new BigDecimal(result.pop().toString());//再取出被减数
result.push(minuend.subtract(meiosis).doubleValue());
operatand.poll();
}
else if(operatand.peek().equals("*"))
{
BigDecimal multiplicatoro = new BigDecimal(result.pop().toString());
BigDecimal multiplicatort = new BigDecimal(result.pop().toString());
result.push( multiplicatoro.multiply(multiplicatort).doubleValue());
operatand.poll();
}
else if(operatand.peek().equals("/"))
{
BigDecimal divisor = new BigDecimal(result.pop().toString());//先取出除数
BigDecimal dividend = new BigDecimal(result.pop().toString());//再取出被除数
if(divisor.doubleValue()==0.0)
{
throw new Exception();
}
else
{
result.push(dividend.divide(divisor,10,BigDecimal.ROUND_HALF_UP).doubleValue());
}
operatand.poll();
}
}
return result.peek();
}
}