stack为ADT中的一种数据结构,该结构特点是先进后出,Stack继承了Vector,Vector继承了AbstractList类,由此可见Stack也是集合。他的实现方法一般有两种:
一种为单链表(node只有一个next指针的LinkedList),另一种是是数组。jdk中是以数组实现的。
1.栈的特点为先进后出。
栈中的一些常用方法:
pop()从栈中弹一个出来(即从栈顶删除一个元素,返回该元素),
peek()获取栈顶元素(不从栈顶删除),
push(E e)压入一个元素到栈顶(即从栈顶添加一个元素),
empty(判断栈是否为空),
search(Object o)从栈中搜索一个元素。
以上为Stack中的实现的所有方法。
2.栈的应用
如何计算表达式 a+b*c+(d*e+f)*g
1.要计算这个表达式,首先要知道后序表达式
通常我们用到的表达式为中序表达式,即运算符号在运算值的中间,就像a+b, a+b*c+(d*e+f)*g,
但其实还有另一种表达式,叫后序表达式。该表达式是将运算符号放在运算值后来进行计算的,
如:a+b 写成 ab+, a+b*c写成 abc*+, a+b*c+d+e/f写成 abc*+def/++
中序表达式如何转换为后序表达式,例如String str = a+b*c+(d*e+f)*g 输出结果 abc*+de*f+g*+
1.首先有两个存储的对象,一个为后序表达式的结果值可变字符串sf,一个存储运算符号的stack
2.遍历字符串str,获取每一项的值item,如果是运算值(abc),添加到sf;
3.如果是运算符号:
1)如果是 */( 直接添加到stack
2)如果是 +- ,
如果stack栈顶的元素为+-或空的时候直接添加到stack,
如果为*/则弹出stack中的所有元素( 如果有(,则弹到( ),然后添加到sf中。然后将+-压入stack
3)如果是 ) , 弹出(之前的所有元素,然后添加到sf中
3.弹出stack中所有的元素,然后添加到sf中
下边是代码
1 private static Set<String> diginal = new HashSet<String>();// 存放表达式中的运算符号 2 3 public static void main(String[] args) { 4 String str = "a+b*c+(d*e+f)*g"; 5 Pattern p = Pattern.compile("[+*()-/]"); 6 Matcher m = p.matcher(str); 7 while (m.find()) { 8 String item = m.group(); 9 diginal.add(item); 10 } 11 } 12 13 /** 14 * 中序表达式转后续表达式 15 * 16 * @param str 17 * @return 18 */ 19 public static String transfer(String str) { 20 boolean flag = false;// 判断有没有( 21 StringBuffer sf = new StringBuffer(); 22 Stack<Character> stack = new Stack<Character>(); 23 for (int i = 0; i < str.length(); i++) { 24 char item = str.charAt(i); 25 if (!diginal.contains(item + "")) { 26 sf.append(item); 27 } else { 28 if (item == '+' || item == '-') { 29 if (!stack.isEmpty() 30 && (stack.peek() == '*' || stack.peek() == '/')) { 31 while (!stack.isEmpty()) { 32 if (flag && stack.peek() == '(') { 33 break; 34 } 35 sf.append(stack.pop()); 36 } 37 stack.push(item); 38 } else { 39 stack.push(item); 40 } 41 } else if (item == ')') { 42 while (stack.peek() != '(') { 43 sf.append(stack.pop()); 44 } 45 stack.pop(); 46 } else { 47 if (item == '(') { 48 flag = true; 49 } 50 stack.add(item); 51 } 52 53 } 54 } 55 while (!stack.isEmpty()) { 56 sf.append(stack.pop()); 57 } 58 return sf.toString(); 59 }
2.通过后序表达式计算值(只给出结果形式的字符串,)
1.初始化两个变量, 结果字符串sf,存放运算值的stack
2.遍历后序表达式字符串str, 每一项为item
3.当item为运算值的时候, 添加到stack, 如果是+-*/,则从stack栈顶弹出两个元素, 然后进行运算, 然后将结果值压入到stack中。
下边是代码
1 /** 2 * 计算 3 * 4 * @return 5 */ 6 public static String cal(String str) { 7 Stack<String> stack = new Stack<String>(); 8 StringBuffer sf = new StringBuffer(); 9 for (int i = 0, n = str.length(); i < n; i++) { 10 char item = str.charAt(i); 11 if (!(item == '+' || item == '-' || item == '*' || item == '/')) { 12 stack.push(item + ""); 13 } else { 14 String b = stack.pop(); 15 String a = stack.pop(); 16 sf.append(b).append(item).append(a); 17 stack.push("(" + a + item + b + ")");// 用括号括起来表明计算结果 18 } 19 } 20 21 return stack.pop(); 22 }