计算器设计

概要

利用awt完成计算器gui设计。

利用中缀转后缀表达式的方法实现带括号的混合运算。

能通过界面按钮控件输入并实现算术表达式,输入的表达式即时在控件中显示,按下“=”按钮能实现运算,并将运算结果输出在控件中显示;要求能保存和浏览历史表达式的运算记录。

GUI设计

设计两个文本框,上文本框进行算式的事实更新,下文本框用于显示当前的输入以及最后的结果。

通过CE按钮清空上下文本框。

通过Del按钮回退一个操作。

通过“历史”或“记录”这两个按钮打开新窗口,里面保存了之前的算式和结果。

±符号用于正负运算。

“.”小数点用于包含小数的运算数。

根据表达式长度动态改变上下文本框字体大小,以保证上下文本框内容能在文本框中完整显示。

剩下的数字以及加减乘除和左右括号不多做解释。

计算器实现的功能

1.简单的表达式计算,包括 + - * /运算符,正负号百分数及括号功能,以及退格,清空。

2.输入表达式时自动更新上下两文本框(仿Windows自带计算器界面),并将最后的运算结果显示在下方文本框,将表达式显示在上方文本框。

3.简单的表达式检查功能,能够检查括号不匹配、除以零等部分表达式错误。

4.运算符输入限制和辅助:连续输入运算符时,不会连续向表达式中添加运算符,而是进行运算符更新

5.小数点限制:在一个运算数中若输入小数点则小数点按键暂时失效,以保证每个运算数只有一个小数点;另外,当按下小数点时,若下方文本框中没有内容或者仅有运算符,则自动在小数点前添加数字0。

6.数字及小数点输入限制和辅助:输入右括号之后数字键及小数点键暂时失效,输入运算符之后重新激活。

7.允许输入多层括号,将按照优先级进行计算。

计算器未能实现的功能

在缺失右括号时自动补上右括号。

BUG

1.数字后面可以加‘(’。

解决方案:数字后按‘(’时在左括号前加乘号。

2.‘(’后可以加操作符。

解决方案:添加约束条件,下文本框第一个字符是左括号时,运算符失效(因为左括号永远在下文本框的第一位)

3.按了“历史记录”按钮后小数点失效。

解决方案:给历史记录添加条件,并且与其他按钮的调剂同级

4.“历史记录”按钮被当做操作符。

解决方案:同上

5.运算符后直接接右括号

解决方案:加约束条件,最后一个字符如果是运算符或者小数点则右括号失效。

6.数字后可以加右括号

解决方案:增加限制条件,下文本框开头如果非左括号则右括号失效。

7.历史记录只显示最近的一次运算。

解决方案:设x用来保存每次的计算结果。

x = x+"\r\n" +strUpper+"="+strUnder;

8.历史记录中按过等号就会被记录。

解决方案:进行判断,如果下文本框或者上文本框为空,则x = x(待优化),最终效果如下

9.加了左括号没加右括号,点击等号报错,用户友好型差。

解决方案:暂未解决,目前无法做到自动添加括号。

10.右括号之后不能再加运算符和数字。按了等号后不输出结果。

解决方案:找到问题代码,在解决左括号后可以加运算符的bug时添加了这条约束,导致bug,具体原因不明。但是推测bug是因为按下右括号后,下文本框空,上不空导致的。于是在这条约束中添加下不空的条件,最终解决了bug。

解决前:

解决后:

11.如图,小数点后可以直接接运算符。

解决方案:增加约束条件

else if (!strUnder.isEmpty()&&strUnder.charAt(strUnder.length()-1)=='.'){}

12.第一个字符不能是左括号

解决方案:目前找到问题是出在这段代码。

if ((strUnder.charAt(strUnder.length()-1)<='9')&&(strUnder.charAt(strUnder.length()-1)>'0')){//如果数字后按左括号
                    //则会自动在左括号前加乘号
                    strUpper = strUnder+"*";
                    strUnder = cmd;
                }

else if (strUnder.charAt(strUnder.length()-1)=='.'){}//小数点后不能直接加左括号

此代码原本是用来解决bug1以及小数点后可以接左括号的bug的。推测是 当下文本框为空时,限制条件则失效报错。于是添加新的限制条件“当下文本框非空”后问题解决。

新代码如下:

else if(cmd.equals("(")) {
                if ((!strUnder.isEmpty())&&(strUnder.charAt(strUnder.length()-1)<='9')&&(strUnder.charAt(strUnder.length()-1)>'0')){//如果数字后按左括号
                    //则会自动在左括号前加乘号
                    strUpper = strUnder+"*";
                    strUnder = cmd;
                }
                else if ((!strUnder.isEmpty())&&strUnder.charAt(strUnder.length()-1)=='.'){}//小数点后不能直接加左括号

                else{
                strUpper += strUnder;
                    strUnder = cmd;
                }

            }

13.小数点后直接加左括号运算出错

解决方案:增加约束条件,使小数点后不能接左括号。

 else if (strUnder.charAt(strUnder.length()-1)=='.'){}

算法(单栈法)

左右括号匹配,利用栈sta来解决。从前往后遍历式子,如果遇到左括号入栈,遇到右括号,左括号出栈。如果栈空或者栈顶非左括号,则说明右括号多了,返回false。同理若遍历结束后栈非空,说明左括号多了,返回false。

计算式将中缀表达式转换为后缀表达式,并在运算数与运算符之间添加分隔符$,最后进行后缀表达式的计算。中缀表达式储存在str中,后缀表达式储存在s中。

数字与运算符直接用$隔开。数字直接进s。

看到左括号直接入栈。

栈空直接入栈。

优先级高的符号直接入栈。

加号和减号优先级只比左括号高,所以只需判断是否空栈或者是否栈顶为左括号,若是,则入栈,若不是,则弹出,进s并加$号与下一个数字或字符隔开。

乘号和除号优先级比加减和左括号高,所以只需判断是否为空栈或者是否栈顶为乘号或除号,若是,则弹出,进s并加$号与下一个数字或字符隔开,若不是,则入栈。

遇到右括号,将栈顶弹出,进s并加$号与下一个数字或字符隔开,直到遇到左括号,将左括号弹出。

式子结束后将栈内剩余运算符弹出,进s并加$号与下一个数字或字符隔开。

后缀表达式运算:遇到操作数入栈,遇到操作符,将栈顶两个操作数运算后再放入栈。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值