public class LinkedStack<T> { Node<T> head = new Node(null); public static void main(String[] args) { System.out.println("计算"); /* * 这个程序还存在问题 * 计算 2*3+5-5*2 正确,计算 1-2*1-2+5/2-5*2 错误 * */ calculation("1-2*1-2+5/2-5*2"); calculation("2*3+5-5*2"); /* * 步骤分析: * 1-2*1-2+5/2-5*2 * 1-2 * 1-2*1(* 大于 -,记录) * 1-2-2 (- 小于等于 *,先计算再记录 ) * 1-0+5(在这里出错了,存在连续多个相同优先级时,计算错误) * */ } /* * 这个方法的算法是: * 1. 规定 *(乘),/(除) 的优先级为 1,规定 +(加),-(减)的优先级为 0 * 2. 遍历传入的字符传,若字符为操作数则入操作数栈,若字符为操作符执行 3 * 3. 判断操作符栈是否为空,为空则直接入操作符栈,否则判断当前操作符优先级是否大于操作符栈栈顶操作符 * 若优先级大于则入操作符栈,否则就执行 4 再入操作符栈 * 4. 使用操作符栈栈顶的操作符计算操作数栈顶的两个操作数 num1, num2(注意操作数的顺序),然后将结果入操作数栈 * 5. 重复 2 操作,直到字符串结束 * 6. 重复执行 4 直到操作符栈为空,最后操作数栈唯一的元素就是结果 * * */ public static void calculation(String s) { LinkedStack<Double> numStack = new LinkedStack(); LinkedStack<Character> operatorStack = new LinkedStack(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); int priority = priority(c); if (priority == -1) { numStack.push(Double.valueOf((c + ""))); } else { if (operatorStack.isEmpty()) { operatorStack.push(c); } else { if (operatorStack.priorityCompare(c) > 0) { operatorStack.push(c); } else { /* * 修复:不加 do-while 时,若两个相同优先级的运算相连,计算就会错误 * 如: 1-2*1-2+5/2-5*2 * */ do { double num1 = numStack.pop(); double num2 = numStack.pop(); char operator = operatorStack.pop(); // 注意 num2, num1 顺序不可颠倒,否则 -,/ 运算会有问题 // calculation("2*3+5-5*2"); double res = calculation(operator, num2, num1); numStack.push(res); } while (!operatorStack.isEmpty() && operatorStack.priorityCompare(c) == 0); operatorStack.push(c); } } } } System.out.println("数栈"); numStack.show(); System.out.println("操作符栈"); operatorStack.show(); while (!operatorStack.isEmpty()) { double num1 = numStack.pop(); double num2 = numStack.pop(); char operator = operatorStack.pop(); double res = calculation(operator, num2, num1); numStack.push(res); } System.out.println("结果:"); numStack.show(); } public static int priority(char operator) { switch (operator) { case '*': case '/': return 1; case '+': case '-': return 0; default: return -1; } } public int priorityCompare(char operatorNew) { char operatorOld = (char) head.getNext().getData(); return priority(operatorNew) - priority(operatorOld); } public static Double calculation(char operator, double num1, double num2) { switch (operator) { case '*': return num1 * num2; case '/': return num1 / num2; case '+': return num1 + num2; case '-': return num1 - num2; default: return null; } } public boolean isEmpty() { return head.getNext() == null; } public void push(T value) { Node n = new Node(value); if (isEmpty()) { head.setNext(n); } else { n.setNext(head.getNext()); head.setNext(n); } } public T pop() throws RuntimeException { if (isEmpty()) { throw new RuntimeException("栈空!"); } Node temp = head.getNext(); head.setNext(temp.getNext()); return (T) temp.getData(); } public void show() { if (isEmpty()) { System.out.println("栈空~~~~"); } Node temp = head.getNext(); while (temp != null) { System.out.println(temp); temp = temp.getNext(); } } } class Node<T> { private T data; private Node next; public T getData() { return data; } public void setData(T data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } public Node(T data) { this.data = data; } @Override public String toString() { return "Node{" + "data=" + data + '}'; } }
使用栈,计算表达式
最新推荐文章于 2022-10-26 11:33:51 发布