package stack; import java.util.Stack; /** * Created by Lanxiaowei * Craated on 2016/12/11 17:29 * 使用栈计算表达式值 */ public class EvaluateExpression { public static void main(String[] args) { String exp = "(1+2+3)*10-2*2-6*2"; int result = calculate(exp); System.out.println("result:" + result); } /** * 从指定位置开始获取表达式中的操作数 * @param exp 表达式 * @param pos 起始索引位置 * @return */ public static String getDigt(String exp,int pos) { if(!Character.isDigit(exp.charAt(pos))) { //如果获取到的是左括号,返回提取操作数失败 if(exp.charAt(pos) == '(') { return "false"; } throw new IllegalArgumentException("Invalid expression:" + exp); } int num = 0; while(pos < exp.length() && Character.isDigit(exp.charAt(pos))) { num = num * 10 + exp.charAt(pos++) - '0'; } return num + ""; } /** * 获取指定位置的操作符 * @param exp * @param pos * @return */ public static char getOper(String exp,int pos) { switch (exp.charAt(pos)) { case '+' : case '-' : case '*' : case '/' : case '(' : case ')' : return exp.charAt(pos); default: throw new IllegalArgumentException("Invalid expression:" + exp); } } /** * 获取运算符的优先级 * @param oper * @return */ public static OperatorLevel getOperatorLevel(char oper) { switch (oper) { case '+' : case '-' : return OperatorLevel.LOW; case '*' : case '/' : return OperatorLevel.HIGH; default: throw new IllegalArgumentException("Invalid Operator:" + oper); } } /** * 计算两个操作数的值 * @param leftNum * @param oper * @param rightNum * @return */ public static int opt(int leftNum,char oper,int rightNum) { int result = 0; switch (oper) { case '+' : result = leftNum + rightNum; break; case '-' : result = leftNum - rightNum; break; case '*' : result = leftNum * rightNum; break; case '/' : //除数为零的情况 if (rightNum == 0) { throw new IllegalArgumentException("The divisor MUST NOT be zero"); } else { result = leftNum / rightNum; } break; default: throw new IllegalArgumentException("Invalid Operator:" + oper); } return result; } /** * 比较两个操作符的优先级 * @param oper1 操作符1 * @param oper2 操作符2 * @return */ public static boolean isGreater(char oper1,char oper2) { return getOperatorLevel(oper1).getValue() > getOperatorLevel(oper2).getValue(); } /** * 计算表达式求值 * @param exp * @return */ public static int calculate(String exp) { if(null == exp || "".equals(exp)) { throw new IllegalArgumentException("Invalid expression:" + exp); } exp = exp.replace(" ", ""); exp = "(" + exp + ")"; //操作数栈 Stack<Integer> numStack = new Stack<Integer>(); //操作符栈 Stack<Character> operStack = new Stack<Character>(); int status = 0; int pos = 0; Integer tempNum = 0; char tempOper = '0'; char tempOper2 = '0'; int leftNum = 0; int rightNum = 0; String tem = ""; while (pos < exp.length()) { switch (status) { case 0: //提取操作数 //如果提取操作数不成功,则进入status=2步骤 tem = getDigt(exp, pos); if ("false".equals(tem)) { status = 2; break; } tempNum = Integer.valueOf(tem); //操作数压栈 numStack.push(tempNum); //进入步骤1 status = 1; pos = pos + tem.length(); break; case 1: //提取操作符 tempOper = getOper(exp,pos); //如果提取到的是左括号,则抛出异常 if(tempOper == '(') { throw new IllegalArgumentException("Invalid expression:" + exp); } //如果提取到的是右括号,则需要进行计算 if(tempOper == ')') { while (true) { //获取栈顶元素 tempOper = operStack.peek(); operStack.pop(); if(tempOper == '(') { break; } rightNum = numStack.pop(); leftNum = numStack.pop(); tempNum = opt(leftNum,tempOper,rightNum); numStack.push(tempNum); } status = 1; pos++; } else { if(operStack.empty()) { operStack.push(tempOper); status = 0; pos++; } else { tempOper2 = operStack.peek(); while (tempOper2 != '(' && !isGreater(tempOper,tempOper2)) { rightNum = numStack.pop(); leftNum = numStack.pop(); tempNum = opt(leftNum,tempOper2,rightNum); numStack.push(tempNum); operStack.pop(); if(operStack.empty()) { break; } tempOper2 = operStack.peek(); } operStack.push(tempOper); status = 0; pos++; } } break; case 2: //提取左括号( char oper = getOper(exp, pos); //如果获取到的不是左括号,则提示表达式输入不合法 if (oper != '(') { throw new IllegalArgumentException("Invalid expression:" + exp); } operStack.push(oper); //进入步骤0提取操作数,因为左括号后面紧跟的必须是操作数 status = 0; pos++; break; } } if(numStack.empty()) { throw new IllegalArgumentException("Invalid expression:" + exp); } tempNum = numStack.pop(); if(!numStack.empty()) { throw new IllegalArgumentException("Invalid expression:" + exp); } return tempNum; } }
相关推荐
数据结构试验,栈的应用,用栈计算表达式的值
静态栈实现表达式求值的知识点总结 一、静态栈的定义和基本操作 静态栈是一种数据结构,用于存储和管理元素的集合。静态栈可以通过 Push 和 Pop 操作来实现元素的添加和删除。 * 静态栈的定义:静态栈可以用...
在这个Java实现的例子中,“用栈计算表达式”的方法主要涉及到两个方面:解析表达式和进行计算。 首先,我们要理解如何解析表达式。表达式通常包含操作数(numbers)和运算符(operators)。在Java中,我们可以创建...
源代码文件可能包含了具体的编程语言实现,如C++、Java或Python,通过阅读和分析这些代码,可以更直观地了解如何在实际编程环境中运用栈来计算表达式的值。 总之,利用栈求表达式的值是一种高效且实用的方法,它...
### 数据结构栈实现表达式求值 #### 一、引言 在计算机科学领域,数据结构是存储和组织数据的一种特殊方式,它不仅能够提高算法的效率,还能够简化复杂问题的解决过程。栈是一种非常重要的线性数据结构,遵循后进先...
为了更好地理解如何使用栈解决表达式求值问题,我们可以通过以下步骤来解析这个问题: 1. **初始化栈**:首先需要创建两个栈,一个用于存储操作数(数值),另一个用于存储操作符(如加减乘除等)。操作数栈用来...
C++用栈实现表达式求值,经过验收的,可以运行,没有问题
栈是一种特殊的线性数据结构,遵循“后进先出”(LIFO)的原则,非常适合处理具有运算顺序的计算问题,如数学表达式的求值。 首先,我们需要理解栈的基本操作。栈主要有两个基本操作:压栈(Push)和弹栈(Pop)。...
- 主要技术线路:使用栈来解析和计算表达式,首先扫描输入,遇到数字就入栈,遇到运算符则根据运算符的优先级与栈顶元素进行操作。 - 程序运行结构图:通常包括用户界面,输入处理,表达式解析,计算,结果输出...
在这个“利用栈求表达式的值”的项目中,我们探讨的是如何使用栈这种特殊的数据结构来解决数学表达式求值的问题,这非常适合小学生进行编程启蒙学习,并且能够提供评估结果的分数,增强学习的趣味性。 栈是一种具有...
利用栈实现表达式求值,可以计算加减乘除。留出接口,可以扩展。
- **初始化栈**:创建一个新的空栈,通常通过将栈顶指针设为 -1 或者栈容量的初始值来实现。 - **判栈空否**:检查栈顶指针是否为栈的初始状态,如果是则栈为空。 - **入栈**:将一个元素添加到栈顶,增加栈顶...
栈在表达式求值中的作用主要体现在两个方面:括号匹配和算术运算的计算。首先,我们需要理解表达式的两种形式:中缀表达式(如2 + 3 * 4)和后缀表达式(也叫逆波兰表示法,如2 3 4 * +)。中缀表达式是我们常见的...
在本主题“用栈计算表达式(C语言版)”中,我们将探讨如何使用栈来解析和计算数学表达式。这里有两个源代码文件:Calculate.c 和 Calculate2.c,它们可能是实现不同算法或优化版本的示例。 栈在计算表达式中的应用...
在本次“数据结构实验——基于栈的表达式求值”中,我们将深入探讨如何利用栈这一数据结构来解决计算表达式的问题。栈是一种特殊的线性数据结构,它遵循后进先出(LIFO)的原则,这使得它在处理逆波兰表示法(也称为...
在本话题中,我们将探讨如何利用栈来求解数学表达式的值,具体是通过C++编程语言实现。栈被称为“后进先出”(LIFO)的数据结构,这意味着最后入栈的元素将首先出栈,这一特性使得栈在处理逆波兰表示法(Reverse ...
在本实验“运用栈算数表达式求值”中,我们将使用栈来解决计算四则运算(加、减、乘、除)的算术表达式的问题。 首先,我们需要理解算术表达式的基本构成。一个算术表达式可能包含数字、操作符(如+、-、*、/)以及...
下面是一个简化的例子,展示了如何用顺序栈计算后缀表达式"2 3 + 4 *"的值: 1. 初始化栈。 2. 遍历后缀表达式,遇到数字2和3,依次压栈。 3. 遇到"+",弹出栈顶的2和3,相加得到5,再将结果压栈。 4. 遇到"*",弹...
在计算表达式时,栈可以有效地帮助我们管理运算符和操作数,实现逆波兰表示法(Reverse Polish Notation,RPN)或后缀表达式的求值。 逆波兰表示法是一种没有括号的表达式形式,运算符位于它们的操作数之后。例如,...