前几天,写那个带有算符优先级的计算器的时候用到了栈,又查了一些资料,感觉栈还是很重要的。故而,再次总结一下。
栈是一种先进后出的数据集合。它通过五个操作对类Vector 进行了扩展 ,允许将向量视为堆栈。它提供了通常的push 和 pop 操作,以及取堆栈顶点的peek 方法、测试堆栈是否为空的 empty 方法、在堆栈中查找项并确定到堆栈顶距离的search 方法。
首次创建堆栈时,它不包含项。
它的构造方法是 public Stack()
一共有五个方法,这五个方法在你用到栈的时候基本都会用到,所以要掌握。
1. boolean | empty() 返回值是boolean值。 用于测试栈是否为空。
2. E | peek() 返回值是你定义栈的时候的数据类型。 用于查看栈顶部的对象,但是不从栈中移除。这个很重要,因为它不移除对象,只是查看这个对象,而 pop() 这个方法会从栈中移除栈顶的对象。注意这两个的区别!
3. E | pop() 用于移除堆栈顶部的对象,并返回该对象。
4. E | push(E item) 将item压入栈中,即压入堆栈顶部。
5. int | search(Object o) 查找某对象在堆栈中的位置。返回对象在堆栈中的位置,以1为基数。此方法返回距堆栈顶部最近的出现位置到堆栈顶部的距离;堆栈中最顶部项的距离为1。
下面说一下我的那个计算器吧!
目前一般的计算器进行计算时不能输入括号,而且需要事先得到表达式的各项才能使用它,例如:若直接输入:3+4*5,一般的计算器会在输入乘号时,先得到7,输入完成后的结果是35。
具有算符优先级的计算器就是。按照数学中的符号优先级 来计算。
这里主要用到两个栈,一个符号栈,一个数字栈。
最主要的还是以一个算法 ---- 算符优先算法
OperandType EvaluateExpression(){ //算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符和运算数栈 //OP为运算符集合 InitStack(OPTR); Push(OPTR, '#'); InitStack(OPND); c = getchar(); while(c!= '#' || GetTop(OPTR)!='#'){ if(!In(c, op)){ Push(OPND, c); c = getchar(); }else{ while(Precede(GetTop(OPTR),c)){ case '<'://栈顶元素优先权低 Push(OPTR, C); c = getchar(); break; case '='://脱括号并接受下一个字符 pop(OPTR, x); c = getchar(); break; case '>'://退栈并将运算结果入栈 Pop(OPTR, theta); Pop(OPND, b); Pop(OPND, a); Push(OPND, Operate(a, theta, b)); break; } } } return GetTop(OPND); }
Precede(GetTop(OPTR),c) 这个函数用来比较算符的优先级
Operate(a, theta, b) 这个函数是用来计算结果
最后用GetTop(OPND)取出运算符栈的栈底,即结果存放的位置。。。
以下是我写的具体实现:
//计算结果函数 private static String Operate(String a, String theta, String b) { String result = ""; double reusltDouble = 0.0; double aDouble = Double.parseDouble(a); double bDouble = Double.parseDouble(b); switch (theta) { case "+": reusltDouble = aDouble + bDouble; break; case "-": reusltDouble = aDouble - bDouble; break; case "*": reusltDouble = aDouble * bDouble; break; case "/": if (bDouble != 0.0) { reusltDouble = aDouble / bDouble; } else { System.out.println("被除数不能为0!"); return null; } break; default: System.out.println("操作符输入错误!"); return null; } result = reusltDouble+""; return result; }
//判断符号的优先级 private static String Precede(String ch1, String ch2) { String ch = ""; if (ch1.equals("+")) { if (ch2.equals("+")) { ch = ">"; }else if (ch2.equals("-")) { ch = ">"; }else if (ch2.equals("*")) { ch = "<"; }else if (ch2.equals("/")) { ch = "<"; }else if (ch2.equals("(")) { ch = "<"; }else if (ch2.equals(")")) { ch = ">"; }else if (ch2.equals("#")) { ch = ">"; } }else if (ch1.equals("-")) { if (ch2.equals("+")) { ch = ">"; }else if (ch2.equals("-")) { ch = ">"; }else if (ch2.equals("*")) { ch = "<"; }else if (ch2.equals("/")) { ch = "<"; }else if (ch2.equals("(")) { ch = "<"; }else if (ch2.equals(")")) { ch = ">"; }else if (ch2.equals("#")) { ch = ">"; } }else if (ch1.equals("*")) { if (ch2.equals("+")) { ch = ">"; }else if (ch2.equals("-")) { ch = ">"; }else if (ch2.equals("*")) { ch = ">"; }else if (ch2.equals("/")) { ch = ">"; }else if (ch2.equals("(")) { ch = "<"; }else if (ch2.equals(")")) { ch = ">"; }else if (ch2.equals("#")) { ch = ">"; } }else if (ch1.equals("/")) { if (ch2.equals("+")) { ch = ">"; }else if (ch2.equals("-")) { ch = ">"; }else if (ch2.equals("*")) { ch = ">"; }else if (ch2.equals("/")) { ch = ">"; }else if (ch2.equals("(")) { ch = "<"; }else if (ch2.equals(")")) { ch = ">"; }else if (ch2.equals("#")) { ch = ">"; } }else if (ch1.equals("(")) { if (ch2.equals("+")) { ch = "<"; }else if (ch2.equals("-")) { ch = "<"; }else if (ch2.equals("*")) { ch = "<"; }else if (ch2.equals("/")) { ch = "<"; }else if (ch2.equals("(")) { ch = "<"; }else if (ch2.equals(")")) { ch = "="; } }else if (ch1.equals(")")) { if (ch2.equals("+")) { ch = ">"; }else if (ch2.equals("-")) { ch = ">"; }else if (ch2.equals("*")) { ch = ">"; }else if (ch2.equals("/")) { ch = ">"; }else if (ch2.equals("(")) {//此时会报错! System.out.println("语法错误!()"); ch = " "; }else if (ch2.equals(")")) { ch = ">"; }else if (ch2.equals("#")) { ch = ">"; } }else if (ch1.equals("#")) { System.out.println(ch2); if (ch2.equals("+")) { ch = "<"; }else if (ch2.equals("-")) { ch = "<"; }else if (ch2.equals("*")) { ch = "<"; }else if (ch2.equals("/")) { ch = "<"; }else if (ch2.equals("(")) {//此时会报错! ch = "<"; }else if (ch2.equals(")")) { ch = " "; System.out.println("语法错误!#)"); }else if (ch2.equals("#")) { ch = "="; } } return ch; }
// 计算器 public static double EvaluateExpression() { double result = 0.0; Stack<String> OPTR = new Stack<String>(); Stack<String> OPND = new Stack<String>(); OPTR.push("#"); int i = 0; String c = ""; c = tolArray[i]; while (!c.equals("#") || !OPTR.peek().equals("#")) { System.out.println(OPTR.peek()); if (!exitInOtherArray(c)) { System.out.println(c); OPND.push(c); i++; c = tolArray[i]; } else { System.out.println(OPTR.peek()); System.out.println(c); switch (Precede(OPTR.peek(), c)) { case "<": OPTR.push(c); i++; c = tolArray[i]; break; case "=": OPTR.pop(); i++; c = tolArray[i]; break; case ">": String theta = OPTR.pop(); String b = OPND.pop(); String a = OPND.pop(); OPND.push(Operate(a, theta, b)); break; default: break; } } } result = Double.parseDouble(OPND.peek()); return result; }