简易计算器------Java实现(优先级,连续输入)


本程序包含+、-、*、/的优先级运算,包含等于,清除,删除三种功能。
使用到了基础的栈的知识
完整代码在页面底部,传统手艺复制粘贴(手动狗头)可直接运行。

一.页面布局

使用的WindowBuilder对界面进行布局,简单直接。使用方法:安装WindowBuilder插件,然后在eclipse右键-----Open With-----WindowBuilder Editor-----点击底部Design即可。
没安装WindowBuilder也不影响使用。
所有的按钮都是JButton,输出框是JTextField。

二.栈的设计

分为两个栈,数字栈和符号栈。

    Stack<Double> stack1 = new Stack<Double>();       // 数字栈
    Stack<Character> stack2 = new Stack<Character>(); // 符号栈

数字栈:
从输入串起始位置开始读取,读取连续数字并保存为double型,若此时读取到小数点,则读取小数点后的连续数字直到遇见+、-、*、/,作为之前整数的小数部分并入栈,否则就直接入栈。

temp = inputFormula.charAt(i);     // String 取其某一个元素
if ((temp >= '0' && temp <= '9') || temp == '.'){
     //获得各个数字
	double sum = temp - '0';
	int j = i + 1;
	boolean flag = true;     //是否为小数
	int index =  1;         // 记录第几位小数
	while(j < inputFormula.length()){
         //获得了这个完整的数但是它可能为负数
		temp = inputFormula.charAt(j);
		if (temp == '.'){
      // 如果下一位是小数点
			flag = false;
			index = 1;
			++j;
			continue;
	        }
		else if (flag && (temp >= '0' && temp <= '9')){
      // 如果下一位是数字
			sum = sum * 10 + temp - '0';
			++j;
	        }
		else if (!flag && (temp >= '0' && temp <= '9')){
     //如果下一位不是数字
			sum += Math.pow(0.1,index) * (temp -  '0');
			index ++;
			++j;
			}
		else break;
	}           //到此时截止,sum为一个正确的实数

符号栈:
当字符栈为空时,运算符直接入栈;当栈外优先级大于等于栈内优先级,入栈;当栈不为空并且栈外优先级低于栈内优先级,将高优先级的运算先计算了,然后入栈。(此处只有+和*运算,因为我将“-”后面的数保存为负数,将/后的数变为倒数,详情见后面)

else if (temp == '+' || temp == '-' || temp == '*' || temp == '/'  ){
    // 处理字符
// 当栈中为空时  或者  栈外优先级大于等于栈内优先级,入栈
	if (stack2.empty() || getPriority(temp) >= getPriority(stack2.peek().charValue())) // 有优先级的
	{
   
		if(temp == '+' || temp == '-')
		{
   
			stack2.push('+');
		}
		else if(temp == '*' ||temp == '/')
		{
   
			stack2.push('*');
		}
	}
	else{
   
// 当栈不为空  并且  栈外优先级低于栈内优先级,将高优先级的运算先计算了,然后入栈。
		while(!stack2.empty() && (getPriority(temp) < getPriority(stack2.peek().charValue()))){
   
			char c = stack2.peek().charValue();
			stack2.pop();
			double num2 = stack1.peek().doubleValue();
			stack1.pop();
			double num1 = stack1.peek().doubleValue();
			stack1.pop();
			if (c == '+') stack1.push(num1 + num2);
			if (c == '-') stack1.push(num1 + num2);       
			if (c == '*') stack1.push(num1 * num2);
			if (c == '/') stack1.push(num1 * num2);
			}
		stack2.push(temp); // 实际保存进去的运算符未变,变的是需要计算的几个数
		}
	}

三.删除处理

分为归零操作和删除末尾字符的操作。
归零操作直接将文本框的内容设置为0即可

删除末尾字符操作是从尾部删除输入串,符合删除条件时删除尾部,当删的剩第一个数的整数部分时,如果这个数绝对值大于十就可以继续删,绝对值小于十再删将值设置为0。
当字符串内含+、-、*、/、.时说明符合删除条件,可以继续删除。

int returnToZero(String getInput)
{
   
	if(getInput.contains(".")||getInput.contains("+")||getInput.contains("-")
			||getInput.contains("*")||getInput.contains("/"))
		return 1;
	return 0;
}

点击事件:

btnDelete.addActionListener(new ActionListener() {
   
	public void actionPerformed(ActionEvent e) {
   
		inputFormula = textField.getText();
		if(returnToZero(textField.getText()) == 1)  // 可以删的情况(含加减乘除小数点)
		{
   
			textField.setText(textField.getText().substring(0,inputFormula.length()-1));
		}
		// 此时只剩下整数部分,在范围内则设置为0
		else if(Integer.parseInt(textField.getText()) < 10 && Integer.parseInt(textField.getText()) > -10)
		{
   
			textField.setText("0");
		}
		else // 如123  -123
		{
   						
			textField.setText(textField.getText().substring(0,inputFormula.length()-1));
		}
	}
});

四.运算逻辑

加减运算

因为是用栈进行保存数据,遵行后进先出的原则,进行减法运算时,取一个运算符“-”和两个数,若为连续的减法运算,倒数第二个数字被当做正数,故此运算逻辑有误。
直接将“-”后的数字保存为负数,所以运算时使用的只是加法规则且运算逻辑正确。
标记负号

if (inputFormula.charAt(i) == '-' )    // 将后一个数负数保存
{
   
	if(i == 0)                         // 如果第一位是“-”,则传一个0进去,不然数不够用
		stack1.push(0.0);
	isNegative = 1;
}

存为负数

if (isNegative == 1)            // 当标志为1说明sum是一个负数
{
   
	sum = sum * -1;
	isNegative = 0;
}

只入栈加号

if(temp == '+' || temp == '-'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值