微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【数据结构】栈 Stack

1. 栈的定义


2. 栈的实现

2.1. C++ STL中的Stack

参见:http://www.jb51.cc/article/p-pwuxcimt-yt.html

2.2. Java中的Stack

参见:http://docs.oracle.com/javase/7/docs/api/java/util/Stack.html


3. 栈的应用

3.1. 表达式求值

中缀表达式:运算符位于两个操作数之间的表达式;如,1+2×3,中缀表达式的运算一般遵循“先乘除,后加减,从左到右计算,先括号内,后括号外”的规则;中缀表达式不仅要依赖运算符优先级,而且还有处理括号;

后缀表达式:运算符在操作数的后面,如,1+2×3的后缀表达式为123×+;在后缀表达式中已经考虑了运算符的优先级,没有括号,只有操作数和运算符;

后缀表达式求值过程:从左到右读入后缀表达式,如读入的是一个操作数,就将它如数值栈;若读入的是一个运算符op,就从数值栈中连续出栈两个元素,假设为x和y,计算x op y的值,并将计算结果如数值栈。对整个后缀表达式读入结束时,栈顶元素就是计算结果;

表达式求值过程:先将算术表示转换成后缀表达式,然后对该后缀表达式求值;

中缀表达式转后缀表达式过程:设后缀表达式存放在一个数组exp中,操作符栈op;

对于表达式中的每个字符ch:

(1) 若ch为数字,将后续的所有数字依次存入数组exp中;

(2) 若ch为“(”,则将此括弧如栈op;

(3) 若ch为")",则将栈op中左括弧"("之前(栈顶到"("之间)的字符依次删除并存入数组exp中,然后将左括弧"("删除

(4) 若ch为“+”或“-”,则将当前栈op中"("之前的所有运算符一次删除并存入数组exp中,然后将ch如栈op中;

(5) 若ch为"*"或"/",则将当前栈op中栈顶端连续的"*"或"/"删除,并以此存入数组exp中,然后将ch如栈op中;

(6) 若表达式字符串扫描完毕,则将栈op中的所有运算符一次删除并存入数组exp中,最后得到的表达式的后缀表示在数组exp中。

import java.util.*;
import java.util.Stack;
import java.util.Vector;
import java.io.*;

/**
 * Test
 */
public class Calculator
{
    public static void main(String[] args)
	{
	    String expStr = new String ("(56 - 20) / (4 + 2)");
		Expression exp = new Expression(expStr);
		exp.translatetoPostfixExp();
		System.out.println(exp.getPostfixExpStringValue());
		System.out.println("The result is: " + exp.calculate());
	}
}

/**
 * super class for operator and number
 */
interface BulkObject
{
   public String getStringValue();
}

/**
 * number object
 */
class NumberObject implements BulkObject
{
    private double number = 0.0;
	
	public NumberObject(double num)
	{
	    this.number = num;
	}
	
	public String getStringValue()
	{
	    return String.valueOf(number);
	}
	
	public double getValue()
	{
	    return number;
	}
}

/**
 * operator object
 */
class OperatorObject implements BulkObject
{
    private String operator = new String();
	
    public OperatorObject(String op)
	{
	    this.operator = op;
	}
	
	public String getStringValue()
	{
	    return operator;
	}
	
	public String getValue()
	{
	    return operator;
	}
}

/**
 *  expression object
 */
class Expression
{
    // string of expression
    public String expStr = new String();
	// array of number and operator for post fix expression
	public Vector<BulkObject> postfixExp = new Vector<BulkObject>();
	
	/**
	 * constructor
	 */
	public Expression(String expStr)
	{
	    this.expStr = expStr;
	}
	
	/**
	 * return the string value of the post fix expression
	 */
	public String getPostfixExpStringValue()
	{
	    String strValue = new String();
		
	    for (BulkObject ele : postfixExp)
		{
		    strValue += ele.getStringValue() + " ";
		}
		
		return strValue;
	}
	
	/**
	 * translate the expression to post fix format
	 */
	public void translatetoPostfixExp()
	{
	    // operator stack
	    Stack<OperatorObject> opStack = new Stack<OperatorObject>();
		
		int length = expStr.length();
		
		// for each char in the expression string
		for (int i = 0; i < length; i++)
		{
		    char ch = expStr.charat(i);
			
			switch (ch)
			{
			    // ignore the space
			    case ' ':
				{
				
				}
				break;
				// push stack
			    case '(':
				{
				    opStack.push(new OperatorObject(Character.toString(ch)));
				}
				break;
				// pop all the operators before the '('
				case ')':
				{
				    while (!opStack.empty())
					{
					    OperatorObject op = opStack.pop();
						if (op.getValue().equals("("))
						{
						    break;
						}else
						{
						    postfixExp.add(op);
						}
					}
				}
				break;
				// pop up all the operators before the '(',push '+ -'
				case '+':
				case '-':
				{
				    while (!opStack.empty())
					{
					    if (!opStack.peek().getStringValue().equals("("))
						{
						    OperatorObject op = opStack.pop();
							postfixExp.add(op);
						}else
						{
						    break;
						}
					}
					opStack.push(new OperatorObject(Character.toString(ch)));
				}
				break;
				// pop up all the operators * / in stack,push '* /'
				case '*':
				case '/':
				{
				    while (!opStack.empty())
					{
					    String opStr = opStack.peek().getStringValue();
					    if (opStr.equals("*") || opStr.equals("/"))
						{
						    OperatorObject op = opStack.pop();
							postfixExp.add(op);
						}else
						{
						    break;
						}
					}
					opStack.push(new OperatorObject(Character.toString(ch)));
				}
				break;
				default:
				{
				    // construct the number
					if ((ch >= '0' && ch <= '9') || ch == '.') 
					{
					    String numStr = new String();
						numStr = Character.toString(ch);
						
						while ((i+1)<length)
						{
						    ch = expStr.charat(i + 1);
					        if ((ch >= '0' && ch <= '9') || ch == '.')
					        {
					            numStr += Character.toString(ch);
						        i++;
					        }else
							{
							    break;
							}
						}
					    double num = Double.valueOf(numStr).doubleValue();
					    postfixExp.add(new NumberObject(num));
					}
				}
				break;
			}
		}
		
		// clear the stack of operators,push into vector 
		while (!opStack.empty())
		{
		    postfixExp.add(opStack.pop());
		}
	}
	
	/**
	 * get the value as per the post fix expression.
	 */
	public double calculate()
    {
	    Stack<BulkObject> stack = new Stack<BulkObject>();
		
		for (BulkObject ele : postfixExp)
		{
		    if (ele instanceof NumberObject)
			{
			    stack.push(ele);
			}
			
			if (ele instanceof OperatorObject)
			{
			    // stack: bottom : num2,num1 : top
			    NumberObject num1 = (NumberObject)(stack.pop());
				NumberObject num2 = (NumberObject)(stack.pop());
				
				double num = getValue(num2,num1,(OperatorObject)ele);
				stack.push(new NumberObject(num));
			}
		}
		
		return ((NumberObject)(stack.peek())).getValue();
	}

    /**
     *
     */
    public double getValue(NumberObject num1,NumberObject num2,OperatorObject op)
    {
        String str = op.getValue();
		double num = 0.0;
		
		if (str.equals("+"))
		{
		    num = num1.getValue() + num2.getValue();
		}else
	    if (str.equals("-"))
		{
		    num = num1.getValue() - num2.getValue();
		}else
		if (str.equals("*"))
		{
		    num = num1.getValue() * num2.getValue();
		}else
		if (str.equals("/"))
		{
		    num = num1.getValue() / num2.getValue();
		}
		
		return num;
    }	
}

原文地址:https://www.jb51.cc/datastructure/383133.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐