本程序支持含负数、小数、多位数等多种 *** 作数的处理,可以计算含加、减、乘、除、求余、求幂等多种运算符(“+”、“-”、“*”、“/”)的表达式,并能判断表达式括号是否匹配;从键盘输入一个正确的中缀表达式,将中缀表达式转换为计算机理解的后缀表达式,计算后缀表达式(运算有顺序)的值。
GUI计算器实现对于表达式中的简单错误,能够给出提示信息的d窗,且不允许错误信息进入表达式;
(2)能够处理多种 *** 作符
(3)实现包含简单运算的计算器
2、算法实现 中缀表达式转为后缀表达式参考此文章,有配图好理解
①我们使用一个stack栈结构存储 *** 作符,用一个List结构存储后缀表达式结果,使用map结构来判断运算符的优先级;
②首先读取到数字,直接存入list中;
③当读取到左括号"("时,直接压栈,当读取到运算符时,分两种情况讨论;
-
运算符栈为空,直接入栈
-
当栈顶 *** 作符的优先级 小于 当前运算符优先级时(如+和-的优先级低于 * 和 /),直接入栈;
-
当运算符不为空 且 栈顶 *** 作符的优先级 大于或等于 当前运算符优先级时,循环执行出栈 *** 作并加入list中,直到遇到优先级小于当前运算符的元素为止。循环执行完后再将当前运算符压栈。
PS. 只有遇到右括号时,左括号才出栈;
④当遇到右括号")"时,循环执行出栈 *** 作并加入到list中,直到遇到左括号为止。并将左括号d出,但不加入list中;
⑤表达式的值读取完后,将 *** 作符栈中的所有元素d出并加入到list中;
执行完上面步骤后,list中存储的顺序即为我们转换后的后缀表达式的结果
//中缀表达式转后缀表达式 public void evalRPN() { Stackstack = new Stack<>(); Iterator iterator = expression.iterator(); while(iterator.hasNext()) { String now = iterator.next(); System.out.println(now); if(isNumeric(now)) { suffix.add(now);//数字直接入list }else{ if(stack.isEmpty()) {//判断栈是否为空 stack.add(now); continue; } if(now.equals("(")) {//括号判断,分情况 stack.add(now); }else if(now.equals(")")) { while(true) { if(stack.peek().equals("(")) { stack.pop(); break; }else{ suffix.add(stack.pop()); } } }else{ if(map.get(stack.peek()) < map.get(now) || (stack.peek()).equals("(")) { stack.add(now); }else{ while(true) { suffix.add(stack.pop()); if(stack.isEmpty() == true ||map.get(stack.peek()) < map.get(now)) { stack.add(now); break; } } } } } } suffix.add(stack.pop()); }
碎碎念:迭代器挺好用的
Iterator()方法无论List、Set、Queue,都有个iterator()方法,定义在Collection接口中,而这些线性表和集合都是继承自Collection接口。iterator()方法会返回java.util.Iterator接口的 *** 作对象(Collection收集的所有对象)。
static void forEach(Collection collection) { //借forEach函数来展示迭代器方法 Iterator iterator = collection.iterator(); while(iterator.hasNext()) { out.println(iterator.next()); } }
常用方法
- Iterator= list.iterator() 将集合list变成迭代器it,接下来就可以 *** 作迭代器的方法了
- it.hasNext() 查看是否还有下一个元素
- it.next() 查看一个元素
- it.remove() 删除当前元素并返回
将数字存入stack结构中,从右向左看,遇到运算符则使用stack.popd出最上面的两个数字,运算之后将结果压栈。持续往复,直到读取完表达式,此时栈内剩余的最后一个数值,即为后缀表达式的运算结果。
//后缀表达式计算结果 public void Calculate() { Stack3、GUI实现计算器stack = new Stack<>(); for(int i = 0; i < suffix.size(); i++){ String item = suffix.get(i); if(isNumeric(item)){ //是数字 stack.push(Double.parseDouble(item)); }else { //是操作符,取出栈顶两个元素 Double num2 = stack.pop(); Double num1 = stack.pop(); Double res = 0.0; if(item.equals("+")){ res = num1 + num2; }else if(item.equals("-")){ res = num1 - num2; }else if(item.equals("*")){ res = num1 * num2; }else if(item.equals("/")){ res = num1 / num2; }else if(item.equals("%")){ res = num1 % num2; }else if(item.equals("^")){ res = Math.pow(num1,num2); } System.out.println(num1 + " " +num2+ " " + item + " " + res); stack.push(res); } } area.append("n表达式结果为:"+stack.pop()+"n"); }
实图如下,有些尺寸大小可以按照自己的喜好改。
代码如下:
public class Calculator{ ArrayListexpression = new ArrayList<>();//存储每轮输入字符 String[] Operator = new String[]{"+","-","*","/","%","^","(",".",")"};//运算符集 public static HashMap map = new HashMap<>();//运算符优先级 public static ArrayList suffix = new ArrayList<>();//转为后缀表达式 int bracket = 0;//前括号个数 Jtextarea area;//显示屏 public Calculator() { } public void createCalculator () { Jframe f = new Jframe("简版计算器"); f.setBounds(400,200,300,360); f.setLayout(new FlowLayout(1,8,12)); //显示屏 area = new Jtextarea(4,24); area.setEditable(false); f.add(area); JPanel p = new JPanel(); p.setLayout(new GridLayout(6,6,10,12)); f.add(p); //按键 JButton bracket1 = new JButton("(");p.add(bracket1); JButton bracket2 = new JButton(")");p.add(bracket2); JButton remainder = new JButton("%");p.add(remainder); JButton division = new JButton("/");p.add(division); JButton seven = new JButton("7");p.add(seven); JButton eight = new JButton("8");p.add(eight); JButton nine = new JButton("9");p.add(nine); JButton multiplication = new JButton("*");p.add(multiplication); JButton four = new JButton("4");p.add(four); JButton five = new JButton("5");p.add(five); JButton six = new JButton("6");p.add(six); JButton subtraction = new JButton("-");p.add(subtraction); JButton one = new JButton("1");p.add(one); JButton two = new JButton("2");p.add(two); JButton three = new JButton("3");p.add(three); JButton addition = new JButton("+");p.add(addition); JButton power = new JButton("^");p.add(power); JButton zero = new JButton("0");p.add(zero); JButton point = new JButton(".");p.add(point); JButton result = new JButton("=");p.add(result); JButton clear = new JButton("清屏");p.add(clear); f.setVisible(true); Priority(); bracket1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(expression.size() == 0) { expression.add("("); area.append("("); bracket++; return; }else{ for(int i = 0; i < Operator.length; i++) { if(expression.get(expression.size()-1).equals(Operator[i])) { expression.add("("); area.append("("); bracket++; return; } } new MyDialog("数字之后不可以直接使用前括号!"); } } }); bracket2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(expression.size() == 0) { new MyDialog("不可以直接使用后括号!"); return; }else{ for(int i = 0; i < Operator.length; i++) { if(expression.get(expression.size()-1).equals(Operator[i])) { new MyDialog("运算符后不可以使用后括号!"); return; } } } if(bracket > 0) { expression.add(")"); area.append(")"); bracket--; }else{ new MyDialog("没有前括号与后括号对应~"); } } }); remainder.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageSymbol("%"); } }); division.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageSymbol("/"); } }); seven.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("7"); } }); eight.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("8"); } }); nine.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("9"); } }); multiplication.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageSymbol("*"); } }); four.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("4"); } }); five.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("5"); } }); six.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("6"); } }); subtraction.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageSymbol("-"); } }); one.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("1"); } }); two.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("2"); } }); three.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageNum("3"); } }); addition.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageSymbol("+"); } }); power.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { StorageSymbol("^"); } }); zero.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(expression.get(expression.size()-1).equals("%") || expression.get(expression.size()-1).equals("/")) { new MyDialog("分母不可以为零!"); return; }else{ StorageNum("0"); } } }); point.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(expression.size() == 0) { new MyDialog("小数点使用不规范!"); return; }else{ if(isNumeric(expression.get(expression.size()-1)) == true) { int serial = expression.size()-1; String str = expression.get(serial); if(str.charAt(str.length()-1) == '.') { new MyDialog("小数点重复使用!"); return; }else{ expression.set(serial,expression.get(serial) + "."); area.append("."); } return; }else{ new MyDialog("小数点使用不规范!"); return; } } } }); result.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 获取文本框的值 area.append("="); evalRPN(); Calculate(); } }); clear.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 获取文本框的值 area.setText(""); expression.clear(); bracket = 0; suffix.clear(); } }); } }
d窗的代码如下:
public class MyDialog { public MyDialog(String str) { Jframe dia = new Jframe(); dia.setLayout(new FlowLayout(1,15,16)); dia.setBounds(450,250,250,120); JLabel text = new JLabel(str); dia.add(text); JButton confirm = new JButton("确定"); dia.add(/confirm/i); dia.setVisible(true); /confirm/i.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //内存中释放掉 dia.dispose(); } }); } }
4、新的体会
这次算是一次比较仓促的课设,一天激情敲代码搞完的项目,本身质量不算好,但基本 *** 作已经实现,也算是学到了一点点东西。这篇文章还有几个判断的函数没有放进去,想要代码的私信我。其实是很简单的东西,大家还是要动手敲代码,养成自己做项目的流程,效率会提高超多!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)