简单的计算器 -- 第一版

    科技2023-09-19  74

    简易版计算器

    功能:计算一个简单字符串的值

    所输入的字符串仅包含‘+’、‘-’、‘*’、‘/’、‘(’、’)’以命令行的形式输入和呈现效果

    知识点

    中缀表达式转逆波兰式 – 编译原理Queue、Stack基于Java

    中缀转换方式:

    从左到右进行遍历运算数,直接输出到队列左括号,直接压入堆栈,(括号是最高优先级,无需比较)(入栈后优先级降到最低,确保其他符号正常入栈)右括号,(意味着括号已结束)不断弹出栈顶运算符并输出至队列直到遇到左括号(弹出但不输出)运算符,将该运算符与栈顶运算符进行比较, 1)如果优先级高于栈顶运算符则压入堆栈(该部分运算还不能进行), 2)如果优先级低于等于栈顶运算符则将栈顶运算符弹出并输出,然后比较新的栈顶运算符. (低于弹出意味着前面部分可以运算,先输出的一定是高优先级运算符,等于弹出是因为同等优先级,从左到右运算) 直到优先级大于栈顶运算符或者栈空,再将该运算符入栈.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符入队列.

    计算逆波兰式:

    判断队头元素,数字即入栈如果是运算符,计算结果并结果入栈直至队列为空,此时栈顶元素即为目标值 import java.util.*; /** * * @author 路瞳 * @email : 2326713669@qq.com * @date 10/6/2020 * @function * 0、计算一个简单字符串的值(仅包含‘+’、‘-’、‘*’、‘/’、‘(’、')') * 1、首先利用栈将中缀表示式转换为后缀表达式即逆波兰式 * 2、后缀表达式求解 * * @result * 能够完成0~9的加减乘除,返回值为一个double类型 */ public class Calculating { private String tar; private Stack<Character> stack = new Stack<Character>(); // //this string can be calculated // private boolean isTrue = true; // Calculating(String string) { this.tar = string; } // public boolean getRes() { // return this.isTrue; // } /** * * @return return a repolish queue */ private Queue<Character> transToRePolish() { char[] chars = tar.toCharArray(); Queue<Character> queue = new LinkedList<Character>(); for (char ch : chars) { if (isNum(ch)) { queue.offer(ch); } else if (ch == '(') { stack.push(ch); } else if (ch == ')') { while (stack.peek() != '(') { queue.offer(stack.pop()); } if (stack.peek() == '(') { stack.pop(); } } else if (isOp(ch)) { if(stack.isEmpty()){ stack.push(ch); continue; } if (!compPriority(ch, stack.peek())) { while (!stack.isEmpty() && !compPriority(ch, stack.peek())) { queue.offer(stack.pop()); } } stack.push(ch); } } while(!stack.isEmpty()){ queue.offer(stack.pop()); } return queue; } /** * * @param queue * @return result */ private double calRepolish(Queue<Character> queue){ Stack<Integer> res = new Stack<Integer>(); while (!queue.isEmpty()){ Character t = queue.poll(); if(t.equals('+') || t.equals('-') || t.equals('*') || t.equals('/')){ int a = res.pop(); int b = res.pop(); int result = cal(b, a, t); res.push(result); }else{ res.push(t-48); } } return res.pop(); } private int cal(int a, int b, Character t) { //计算 if(t.equals('+')){ return a + b; }else if(t.equals('-')){ return a - b; }else if(t.equals('*')){ return a * b; }else{ return a / b; } } boolean isNum(char ch) { if (ch < '0' || ch > '9') { return false; } return true; } boolean isOp(char ch) { if (ch == '*' || ch == '/' || ch == '+' || ch == '-') { return true; } else { return false; } } /** * @param fir target * @param sec stack top elemnt * @return priority */ boolean compPriority(char fir, char sec) { if(sec == '('){ return true; } // int f = 0; // int s = 0; // if (fir == '*' || fir == '/') { // f = 2; // } // if (sec == '*' || sec == '/') { // s = 2; // } // if (fir == '+' || fir == '-') { // f = 1; // } // if (sec == '+' || sec == '-') { // s = 1; // } if((fir == '*' || fir == '/') && (sec == '+' || sec == '-')){ return true; } else { return false; } //优先级高于栈顶,压入堆栈 // return f > s ? true : false; } public double calculte() { Queue<Character> repolish = transToRePolish(); System.out.println(repolish); double result = calRepolish(repolish); System.out.println(result); return result; } /** * just for test */ public static void main(String[] args) { Calculating ca = new Calculating("3*8+3+2"); ca.calculte(); } }

    参考资料: 1、中缀表达式转逆波兰式 2、数据结构 (C语言版)

    Processed: 0.023, SQL: 8