Java实现简单计算器(四则运算,括号,浮点数)

用堆栈把输入的中缀表达式转化为后缀表达式,然后计算。用的是数据结构里的代码:表达式转换(中缀表达式转为后缀表达式)

import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Main extends JFrame implements ActionListener {

	private String expression;//记录表达式
	private final String[] keys = {"(",")","CE","Back",//按键
								     "7","8","9","+",
								     "4","5","6","-",			
								     "1","2","3","*",	
								     ".","0","=","/"};
	private JTextField result = new JTextField("");//结果 	
	private JButton[] buttons = new JButton[20];//按钮
	
	Main(){
		this.setTitle("简单计算器");
		this.setLocation(500,300);
		JPanel panel = new JPanel();//计算器布局
		panel.setLayout(new GridLayout(6,1));//布局分6行,第一行文本框
		panel.add(result);
		result.setFont(result.getFont().deriveFont((float)30));
		Container[] containers = new Container[5];
		for(int i=0 ; i<5; i++){
			containers[i] = new Container();
			containers[i].setLayout(new GridLayout(1,4));
			panel.add(containers[i]);
		}
		for(int i=0; i<buttons.length; i++){
			buttons[i] = new JButton(keys[i]);
			buttons[i].setFont(buttons[i].getFont().deriveFont((float)25));//设置字体大小
			containers[i/4].add(buttons[i]);
			buttons[i].addActionListener(this);
		}
		getContentPane().add(panel);
		expression="";//表达式为空
	}
	
	public static void main(String[] args) {
		Main calculator = new Main();
		calculator.setSize(400,400);//计算器长宽
		calculator.setVisible(true);	
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String action = e.getActionCommand();
		if(action.equals(keys[2])){//清空键c
			expression = "";
		}else if(action.equals(keys[3])){//删除一个字符back
			expression = expression.substring(0,expression.length()-1);
		}else if(action.equals(keys[18])){//计算结果=
			expression = Calculator.solve(expression);
		}else {
			expression += action;
		}
		result.setText(expression);
	}
}

class Calculator{
	
	public static String solve(String expression){//计算表达式

		double sum=0,flag=0;
		int top=-1;// 存数堆栈的指针
		//Stack<Double> stack1 = new Stack<Double>();Double类型的堆栈会损失精度,如存入2.1取出时就是2.0了
		double[] stack1 =  new double[100];// 存数的堆栈,用数组模拟堆栈
		Stack<Character> stack2 = new Stack<Character>();//存运算符的堆栈
		
		for(int i=0 ; i<expression.length(); i++){
			char p = expression.charAt(i);
			flag = sum = 0;
			if(p >= '0' && p <= '9'){//存入数字
				while(true){
					p = expression.charAt(i);
					if(p == '.') flag = 0.1;
					else {
						if(flag == 0) sum = sum*10+(p-'0');
						else {//小数位处理
							sum += ((p-'0')*flag);
							flag *= 0.1;
						}
					}					
					if(i+1<expression.length()&&((expression.charAt(i+1)>='0'&&expression.charAt(i+1)<='9')||expression.charAt(i+1)=='.')) i++;
					else {
						stack1[++top]=sum;
						break;
					}
				} 
			}
			else {
				if(p=='(') stack2.push(p);
				else if(p == '*' || p == '/') {// 此时运算符是*或/时堆栈中优先级高的先计算
					while(stack2.size()>0 && (stack2.peek()=='*'||stack2.peek()=='/')) {
						double temp = compute(stack1[top--],stack1[top--],stack2.pop());
						stack1[++top] = temp;
					}
					stack2.push(p);//最后放入
				} 
				else if(p=='+'||p=='-') {// 此时运算符是+或-时括号之前的内容都取出来
					while(stack2.size()>0&&stack2.peek()!='(') {
						double temp=compute(stack1[top--],stack1[top--],stack2.pop());
						stack1[++top]=temp;
					}
					stack2.push(p);
				}
				else if(p==')') {// 此时运算符是)时堆栈内容都取出来
					while(stack2.size()>0&&stack2.peek()!='(') {
						double temp = compute(stack1[top--],stack1[top--],stack2.pop());
						stack1[++top] = temp;
					}
					stack2.pop();//取出左括号
				}
			}
		}
		while(stack2.size()>0) {//计算剩下的式子
			double temp=compute(stack1[top--],stack1[top--],stack2.pop());
			stack1[++top] = temp;
		}
		return "" + stack1[top];//double类型强制转为String类型
	}
	
	public static double compute(double a,double b, char p) {//在函数中运算
		double sum = 0;
		if(p=='+') {
			sum = b+a;
		}else if(p=='-') {//要注意用栈顶的数是被减数或者被除数
			sum = b-a;
		}else if(p=='*') {
			sum = b*a;
		}else if(p=='/') {
			sum = b/a;
		}
		return sum;
	}
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值