栈和应用_表达式求值

合集下载

数据结构名词解释考研题库及答案

数据结构名词解释考研题库及答案

数据结构名词解释考研题库及答案数据结构是计算机科学中的重要概念,它是指一组数据的组织方式和操作方法。

在计算机科学的学习和研究中,数据结构是非常基础和核心的内容之一。

对于考研的学生来说,掌握数据结构的相关知识是必不可少的。

在考研题库中,有很多关于数据结构的名词解释题目,下面我将对其中一些常见的名词进行解释,并给出相应的答案。

1. 栈(Stack)栈是一种线性数据结构,它的特点是“后进先出”(Last In First Out,LIFO)。

栈有两个基本操作:入栈(Push)和出栈(Pop)。

入栈操作将元素放入栈的顶部,出栈操作将元素从栈的顶部移除。

2. 队列(Queue)队列也是一种线性数据结构,它的特点是“先进先出”(First In First Out,FIFO)。

队列有两个基本操作:入队(Enqueue)和出队(Dequeue)。

入队操作将元素放入队列的末尾,出队操作将元素从队列的头部移除。

3. 链表(Linked List)链表是一种动态数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

链表有单向链表和双向链表两种形式。

链表的插入和删除操作比较高效,但是访问元素的效率较低。

4. 树(Tree)树是一种非线性数据结构,它由一组节点和连接它们的边组成。

树的一个节点称为根节点,每个节点可以有零个或多个子节点。

树的常见应用包括二叉树、二叉搜索树、平衡二叉树等。

5. 图(Graph)图是一种非线性数据结构,它由一组节点和连接它们的边组成。

图的节点之间可以有多个连接关系,这些连接关系称为边。

图可以分为有向图和无向图两种形式。

以上是一些常见的数据结构名词的解释,接下来我将给出一些相应的考研题目及答案。

1. 问题:栈的应用场景有哪些?答案:栈的应用场景包括函数调用、表达式求值、括号匹配等。

在函数调用中,每次调用函数时,系统会将返回地址和局部变量等信息保存在栈中。

在表达式求值中,可以利用栈来实现中缀表达式转后缀表达式的过程。

栈的实验报告结论(3篇)

栈的实验报告结论(3篇)

第1篇一、实验目的1. 理解栈的基本概念和操作;2. 掌握栈的顺序存储和链式存储实现方法;3. 熟悉栈在程序设计中的应用。

二、实验内容1. 栈的顺序存储结构实现;2. 栈的链式存储结构实现;3. 栈的基本操作(入栈、出栈、判空、求栈顶元素);4. 栈在程序设计中的应用。

三、实验方法1. 采用C语言进行编程实现;2. 对实验内容进行逐步分析,编写相应的函数和程序代码;3. 通过运行程序验证实验结果。

四、实验步骤1. 实现栈的顺序存储结构;(1)定义栈的结构体;(2)编写初始化栈的函数;(3)编写入栈、出栈、判空、求栈顶元素的函数;(4)编写测试程序,验证顺序存储结构的栈操作。

2. 实现栈的链式存储结构;(1)定义栈的节点结构体;(2)编写初始化栈的函数;(3)编写入栈、出栈、判空、求栈顶元素的函数;(4)编写测试程序,验证链式存储结构的栈操作。

3. 栈在程序设计中的应用;(1)实现一个简单的四则运算器,使用栈进行运算符和操作数的存储;(2)实现一个逆序输出字符串的程序,使用栈进行字符的存储和输出;(3)编写测试程序,验证栈在程序设计中的应用。

五、实验结果与分析1. 顺序存储结构的栈操作实验结果:(1)入栈操作:在栈未满的情况下,入栈操作成功,栈顶元素增加;(2)出栈操作:在栈非空的情况下,出栈操作成功,栈顶元素减少;(3)判空操作:栈为空时,判空操作返回真,栈非空时返回假;(4)求栈顶元素操作:在栈非空的情况下,成功获取栈顶元素。

2. 链式存储结构的栈操作实验结果:(1)入栈操作:在栈未满的情况下,入栈操作成功,链表头指针指向新节点;(2)出栈操作:在栈非空的情况下,出栈操作成功,链表头指针指向下一个节点;(3)判空操作:栈为空时,判空操作返回真,栈非空时返回假;(4)求栈顶元素操作:在栈非空的情况下,成功获取栈顶元素。

3. 栈在程序设计中的应用实验结果:(1)四则运算器:成功实现加、减、乘、除运算,并输出结果;(2)逆序输出字符串:成功将字符串逆序输出;(3)测试程序:验证了栈在程序设计中的应用。

C++实例(表达式求值(栈的应用))

C++实例(表达式求值(栈的应用))

表达式求值: 设计⼀个程序实现输⼊⼀个表达式如3*(3+4),以”#”结尾,求出其值。

分析: 先分析⼀下四则运算的规则: 1. 先乘除后加减; 2. 从左到右计算; 3. 先括号内后括号外; 于是我们要把运算符的优先级确定清楚。

这⾥我只⽤这⼏个运算符:+-*/(), 可以知道+-的优先级低于*/,⽽对于(),当第⼀次遇到’(‘时,’(‘后⾯的就优先计算,直到遇到’)’为⽌,可以先把’(’的优先级定为⽐其它⼏个都⾼,然后遇到’)’时把⾥⾯的先算出来,再算括号外⾯的,具体实现在代码中会表现得很清楚。

考试2⼤提⽰这个程序还是⽤栈来实现,具体代码如下。

代码: #include #include using namespace std; const int STACK_INIT_SIZE=100; //The maximize length of stack template class Stack //A class of stack { public: Stack() //Constructor function { base = new int[STACK_INIT_SIZE]; if (!base) { cerr< exit(-1); } top=base; stacksize=STACK_INIT_SIZE; } ~Stack() //Destructor function { if (base) delete[] base; } T GetTop() { if (top==base) { cerr< exit(-1); } return *(top-1); } void Push(T e) { if (top-base>=stacksize) { base=new int[STACK_INIT_SIZE]; if(!base) { cerr< exit(-1); } top=base+STACK_INIT_SIZE; stacksize+=STACK_INIT_SIZE; } *top++=e; } void Pop(T& e) { if (top==base) { cerr< exit(-1); } e=*--top; } private: int *base; int *top; int stacksize; }; string op("+-*/()#"); //The set of operator bool In(char c,string op) //Judge the character whether belong to the set of operator { string::iterator iter=op.begin(); for (;iter!=op.end();++iter) if (*iter==c) return true; return false; } char Precede(char top,char c) //Confirm the precedence of operator { int grade_top=0,grade_c=0; switch (top) { case '#':grade_top=0;break; case ')':grade_top=1;break; case '+':grade_top=2;break; case '-':grade_top=2;break; case '*':grade_top=3;break; case '/':grade_top=3;break; case '(':grade_top=4;break; } switch (c) { case '#':grade_c=0;break; case ')':grade_c=1;break; case '+':grade_c=2;break; case '-':grade_c=2;break; case '*':grade_c=3;break; case '/':grade_c=3;break; case '(':grade_c=4;break; } if (grade_top>=grade_c) { if (top=='('&&c!=')') return ' else if (top=='('&&c==')') return '='; return '>'; } else if (top=='#'&&c=='#') return '='; else return ' } int Operate(int a,char theta,int b) //Calculate { if (theta=='+') return a+b; else if (theta=='-') return a-b; else if (theta=='*') return a*b; else if (theta=='/') return a/b; return 0; } int EvaluateExpression(Stack& OPTR,Stack& OPND) { int a=0,b=0,n=0; char x; char theta; string c; cin>>c; OPTR.Push('#'); while (c[0]!='#'||OPTR.GetTop()!='#') { if (!In(c[0],op)){ n=atoi(&c[0]); OPND.Push(n); cin>>c; } else switch (Precede(OPTR.GetTop(),c[0])) { case ' OPTR.Push(c[0]); cin>>c; break; case '=': OPTR.Pop(x); cin>>c; break; case '>': OPTR.Pop(theta); OPND.Pop(b); OPND.Pop(a); OPND.Push(Operate(a,theta,b)); break; } } return OPND.GetTop(); } int main() { Stack OPTR; Stack OPND; cout< cout< return 0; }。

基于栈的后缀算术表达式求值c语言

基于栈的后缀算术表达式求值c语言

基于栈的后缀算术表达式求值c语言1. 引言1.1 概述本文将讨论基于栈的后缀算术表达式求值的实现过程。

后缀算术表达式(也称为逆波兰表达式)是一种无需括号即可进行运算的表达式表示方法,它将操作符置于操作数之后。

相较于传统的中缀表达式,在计算机程序中处理后缀表达式更为高效和简洁。

1.2 文章结构文章分为五个主要部分:引言、栈的概念及原理、后缀算术表达式的定义和转换、基于栈的后缀算术表达式求值算法实现以及结论与总结。

在引言部分,我们将首先介绍本文的概述和目标,对后续内容进行简要说明。

1.3 目的通过本文,我们旨在让读者了解栈数据结构的基本概念和原理,并且掌握如何利用栈来实现对后缀算术表达式进行求值的算法。

同时,我们将介绍后缀算术表达式的定义和转换方法,并给出基于栈实现该计算方式的详细步骤与示例代码。

通过深入研究并学习这些内容,读者可以加深对栈数据结构和后缀算术表达式的理解,并且能够应用所学知识解决实际问题。

本文不仅适用于计算机科学或相关专业的学生,也适合对数据结构和算法感兴趣的读者阅读和学习。

2. 栈的概念及原理2.1 栈的定义栈是一种具有特定限制条件的线性数据结构,它具备“先进后出”(Last-In-First-Out,LIFO)的特性。

栈可以看作是一个容器,其中可以存储各种类型的数据。

与实际生活中的堆栈类似,栈只允许在其末尾进行插入和删除操作。

在栈中,最后加入的元素首先被访问和处理。

这是由于栈内元素之间的相对位置关系决定的。

插入操作称为“压栈”(Push),删除操作称为“弹栈”(Pop),而从栈顶读取元素或获取栈顶元素但不删除它称为“查看”(Peek)。

2.2 栈的基本操作推入元素:将一个元素添加到栈顶。

如果已经存在满员条件,则无法执行此操作。

弹出元素:从栈顶移除一个元素,并返回移除的值。

如果没有任何元素存在,则无法执行此操作。

查看栈顶元素:获取位于栈顶处的元素值,但不对其进行删除。

判断是否为空:检查栈是否为空。

表达式求值算法总结(C++)

表达式求值算法总结(C++)

表达式求值算法总结(C++)表达式求值,一般采用栈和队列的方式来求值,下面介绍表达式求值的两种算法。

方法一、使用两个栈,一个为操作符栈OPTR(operator),一个是操作数栈OPND(operand)算法过程:当输入3 * ( 4 - 1 * 2 ) + 6 / ( 1 + 1 )时,为简单方便,我们输入时,按照字符的顺序一个一个的处理,比如ch = getchar()。

然后根据ch 的值判断:若ch 是数字,直接压入操作数栈OPND;若ch 是'(',直接入栈OPTR;若ch 是')',若OPTR 和OPND 非空,弹出OPTR的栈顶操作符,弹出OPND栈顶的两个操作数,做运算,然后见个结果压入栈OPND,直到弹出的OPTR栈顶元素时')';若ch 是操作符(比如+, -, *, /),如果OPTR栈顶元素是(,直接入栈OPTR,如果不是'('且OPTR栈非空且栈顶元素操作符的优先级大于ch,那么弹出OPTR的栈顶操作符,并弹出OPND中栈顶的两个元素,做运算,将运算结果入栈OPND,此时,重复这一步操作;否则将ch入栈OPTR;若ch为EOF,说明表达式已经输入完成,判断OPTR是否为空,若非空,一次弹出OPTR 栈顶操作符,并与OPND栈顶两个元素做运算,将运算结果入栈OPND,最后表达式的结果即OPND的栈底元素。

以表达式3 * ( 4 - 1 * 2 ) + 6 / ( 1 + 1 )为例,计算过程如下所示:通过上述的计算过程,写出伪代码如下所示:void GetExpress(Stack * OPTR, Stack * OPND){char ch;while ((ch = getchar ()) != EOF) {if (IsDigit (ch)) {PushStack (OPND, ch);}else if (ch == '(')PushStack (OPTR, ch);else if (ch == ')') {while (!IsStackEmpty(OPTR)) {PopStack (OPTR, op);if (op == ')')break;PopStack (OPND, num2);PopStack (OPND, num1);res = Calc (num1, num2, op);PushStack (OPND, res);}}else if (ch == '+' || ch == '-'|| ch == '*' || ch == '/') {while (!IsStackEmpty (OPTR) && GetTop (OPTR)!='(' && GetTop (OPTR)>ch) { PopStack (OPTR, op);PopStack (OPND, num2);PopStack (OPND, num1);res = Calc (num1, num2, op);PushStack (OPND, res);}if (IsStackEmpty (OPTR) || GetTop(OPTR)=='(')PushStack (OPTR, ch);}}}// 当表达式输入完成后,需要对OPTR栈和OPND中的元素进行运算int GetValue(Stack * OPTR, Stack * OPND){while (!IsStackEmpty (OPTR)) {PopStack (OPTR, op);PopStack (OPND, num2);PopStack (OPND, num1);res = Calc (num1, num2, op);PushStack (OPND, res);}// 最后的操作数栈OPND栈顶元素即是表达式的值return GetTop(OPND);}PS: 上面没有指出表达式非法的情况方法二:采用中缀表达式的方法,求取表达式的中缀表达式,借用一个操作符栈OPTR和中缀表达式队列Queue,求取中缀表达式,然后对中缀表达式求值。

[计算机软件及应用]栈的应用和串图

[计算机软件及应用]栈的应用和串图

A. i-j-1 B. i-j
C. j-i+1 D. 不确定的
5. 若 已 知 一 个 栈 的 入 栈 序 列 是 1,2,3,…,n , 其 输 出 序 列 为 p1,p2,p3,…,pN,若pN是n,则pi是( D)。
A. i
B. n-i C. n-i+1 D. 不确定
6
2. 在作进栈运算时,应先判别栈是否( ① B),在作退栈运算时应 先判别栈是否( ② A )。当栈中元素为n个,作进栈运算时发生上
if(!In(c,OP)){Push(OPND,c); c=getchar();}//不是运算符则进入 栈
switch(Precede(GetTop(OPTR),c)){ case ‘<’: //栈顶元素的优先级低
Push(OPTR, c); c=getchar(); break;
case ‘=’: //脱括号并接受下一个字符;
例1数制转换
除基取余法
十进制N和其它进制数的转换是计算机实原理:
N=(n div d)*d+n mod d
( 其中:div为整除运算,mod为求余运算)
例如 (1348)10=(2504)8,其运算过程如下:
n n div 8 n mod 8
16. 栈在( D)中应用。
A. 递归调用 B. 子程序调用 C. 表达式求值 D. A,B,C
9
注:上述算法的匹配过程易于理解,且在某些应用场合,如文本 编辑等,效率也较高,但是在有些情况下,该算法的效率却很低。
其主串的指针i在不断的回溯,如i=3,变为i=2,i=7变为i=4… 其时间复杂度可达到O(n*m).
列得不到的出栈排列是( )。
A.XYZ

栈的面试题目(3篇)

栈的面试题目(3篇)

第1篇第一部分:基本概念与操作1. 什么是栈?- 栈是一种线性数据结构,遵循后进先出(LIFO)的原则。

它只允许在栈顶进行插入(push)和删除(pop)操作。

2. 栈的基本操作有哪些?- 入栈(push):在栈顶添加一个新元素。

- 出栈(pop):移除栈顶元素。

- 查看栈顶元素(peek 或 top):获取栈顶元素但不移除它。

- 判断栈是否为空(isEmpty):检查栈中是否没有元素。

- 获取栈的大小(size):返回栈中元素的数量。

3. 请用Python实现一个栈的数据结构。

```pythonclass Stack:def __init__(self):self.items = []def is_empty(self):return len(self.items) == 0def push(self, item):self.items.append(item)def pop(self):if not self.is_empty():return self.items.pop()return Nonedef peek(self):if not self.is_empty():return self.items[-1]return Nonedef size(self):return len(self.items)```4. 如何实现一个固定大小的栈?- 在栈类中添加一个计数器来跟踪栈的大小,并在push操作中检查是否已达到最大容量。

5. 请解释栈的两种遍历方法。

- 递归遍历:使用递归方法遍历栈的所有元素。

- 迭代遍历:使用栈的辅助结构(如队列)来实现迭代遍历。

第二部分:栈的应用6. 栈在计算机科学中的应用有哪些?- 函数调用:局部变量和返回地址存储在栈中。

- 表达式求值:逆波兰表达式(RPN)计算。

- 字符串匹配:括号匹配验证。

- 汉诺塔问题:移动塔的步骤可以通过栈来模拟。

7. 请解释如何使用栈实现括号匹配验证。

利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法利用栈来实现算术表达式求值的算法算术表达式是指按照一定规则组成的运算式,包含数字、运算符和括号。

在计算机中,求解算术表达式是一项基本的数学运算任务。

根据算术表达式的性质,我们可以考虑利用栈这一数据结构来实现求值算法。

一、算法思路首先,我们需要明确一个重要概念——逆波兰表达式(ReversePolish notation)。

逆波兰表达式是一种没有括号的算术表达式,其运算规则是先计算后面的数字和运算符,再计算前面的数字和运算符。

例如,对于算术表达式“3+4*5-6”,其对应的逆波兰表达式为“3 45 * +6 -”。

那么,我们可以利用栈来实现将中缀表达式转化为逆波兰表达式的过程,具体步骤如下:1. 创建两个栈——操作数栈和操作符栈。

2. 从左到右扫描中缀表达式的每一个数字和运算符,遇到数字则压入操作数栈中,遇到运算符则进行如下操作:(1)如果操作符栈为空或当前运算符的优先级大于栈顶运算符的优先级,则将当前运算符压入操作符栈中。

(2)如果当前运算符的优先级小于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入操作数栈中,重复此过程直到遇到优先级较低的运算符或操作符栈为空为止,然后将当前运算符压入操作符栈中。

3. 扫描完中缀表达式后,若操作符栈不为空,则将其中所有运算符弹出并加入操作数栈中。

4. 最终,操作数栈中存放的就是逆波兰表达式,我们可以按照逆波兰表达式的计算规则来计算其结果。

二、算法优点利用栈来实现算术表达式求值的算法具有以下优点:1. 代码简洁易懂,易于实现和维护。

2. 由于将中缀表达式转化为逆波兰表达式后,可以减少运算符的优先级关系而消除括号,从而减少求值的复杂度,提高程序的执行效率。

三、代码实现下面是利用栈来实现算术表达式求值的算法的Python代码实现:```pythonclass Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def peek(self):return self.items[-1]def is_empty(self):return len(self.items) == 0def size(self):return len(self.items)def calculate(op_num1, op_num2, operator):if operator == "+":return op_num1 + op_num2elif operator == "-":return op_num1 - op_num2elif operator == "*":return op_num1 * op_num2elif operator == "/":return op_num1 / op_num2def infix_to_postfix(infix_expr):opstack = Stack()postfix_expr = []prec = {"+": 1, "-": 1, "*": 2, "/": 2, "(": 0} token_list = infix_expr.split()for token in token_list:if token.isdigit():postfix_expr.append(token)elif token == '(':opstack.push(token)elif token == ')':top_token = opstack.pop()while top_token != '(':postfix_expr.append(top_token)top_token = opstack.pop()else:while (not opstack.is_empty()) and(prec[opstack.peek()] >= prec[token]):postfix_expr.append(opstack.pop())opstack.push(token)while not opstack.is_empty():postfix_expr.append(opstack.pop())return " ".join(postfix_expr)def postfix_eval(postfix_expr):opstack = Stack()token_list = postfix_expr.split()for token in token_list:if token.isdigit():opstack.push(int(token))else:op_num2 = opstack.pop()op_num1 = opstack.pop()result = calculate(op_num1, op_num2, token) opstack.push(result)return opstack.pop()infix_expr = "3 + 4 * 5 - 6"postfix_expr = infix_to_postfix(infix_expr)print(postfix_expr)print(postfix_eval(postfix_expr))```四、总结算术表达式求值是一项常见的数学运算任务,利用栈这一数据结构来实现求值算法是一种简单有效的方法,它将中缀表达式转化为逆波兰表达式后,可以消除括号并减少运算符的优先级关系,从而提高程序的执行效率。

栈的应用及特性

栈的应用及特性

栈的应用及特性栈是计算机科学中一种非常重要的数据结构,具有广泛的应用和独特的特性。

下面将详细介绍栈的应用及特性。

一、栈的应用:1. 函数调用:在程序执行过程中,函数的调用和返回通常采用栈进行管理。

当一个函数被调用时,函数的参数和局部变量被压入栈中,函数执行完毕后,这些信息会被弹出栈恢复到调用函数的状态。

2. 表达式求值:在编程语言中,栈可用于表达式求值、中缀表达式转换为后缀表达式等相关操作。

通过利用栈的先进后出特性,可以方便地实现这些功能。

3. 递归算法:递归算法中的递归调用也可以通过栈来实现。

当算法需要递归调用时,将函数和相关变量的信息压入栈中,等到递归结束后,再从栈中弹出恢复状态。

4. 括号匹配:栈也常用于判断表达式中的括号是否匹配。

遍历表达式,遇到左括号时压入栈,遇到右括号时弹出栈顶元素,如果匹配则继续,不匹配则判定为括号不匹配。

5. 浏览器的前进后退:浏览器的前进后退功能可以使用栈实现。

每次浏览一个网页时,将该网页的URL压入栈中,点击后退按钮时,再从栈中弹出上一个URL,即可实现返回上一个网页的功能。

6. 撤销操作:在图形界面软件中,通常会有撤销操作。

使用栈可以将每一步操作的状态依次压入栈中,当用户需要撤销时,再从栈中弹出最近的状态,恢复到之前的操作状态。

二、栈的特性:1. 先进后出:栈是一种后进先出(LIFO)的数据结构,即最新添加的元素最先被访问或者删除。

这一特性使得栈能够方便地实现函数调用和返回等操作。

2. 只能操作栈顶元素:由于栈的特性,只能访问或者修改栈顶元素,无法直接访问或者修改栈中的其他元素。

需要先将栈顶元素弹出后,才能访问或者修改下一个栈顶元素。

3. 顺序存储结构:栈可以使用数组或者链表实现。

使用数组实现时,需要指定栈的最大容量,而使用链表实现时,没有容量限制。

4. 操作复杂度:栈的插入和删除操作只涉及栈顶元素,所以其操作复杂度为O(1)。

但是栈的搜索和访问操作需要从栈顶开始遍历,所以其操作复杂度为O(n)。

java栈的用法

java栈的用法

java栈的用法Java栈的用法Java栈是一种非常重要的数据结构,它在Java语言中广泛应用于各种场景,例如方法调用、异常处理、表达式求值等。

本文将介绍Java栈的基本概念、常见操作以及实现方式等内容。

一、基本概念1. 栈的定义栈是一种线性数据结构,它具有后进先出(Last In First Out,LIFO)的特点。

栈可以看作是一个容器,只能在容器的一端进行插入和删除操作。

插入操作称为“进栈”或“压栈”,删除操作称为“出栈”。

2. 栈的实现方式Java中可以使用数组或链表来实现栈。

使用数组实现时,需要定义一个固定大小的数组,并记录当前栈顶元素位置;使用链表实现时,则需要定义一个头节点和一个指向当前节点的指针。

3. 栈的应用场景Java栈在很多场景下都有着重要的应用,例如:- 方法调用:每当调用一个方法时,都会创建一个新的栈帧并压入当前线程对应的虚拟机栈中。

- 异常处理:当抛出异常时,JVM会创建一个异常对象,并将其压入当前线程对应的虚拟机栈中。

- 表达式求值:通过使用两个栈,一个存放操作数,一个存放运算符,可以实现表达式的求值。

二、常见操作1. 压栈(push)将一个元素压入栈顶。

Java代码示例:```public void push(E item) {ensureCapacity(size + 1);elements[size++] = item;}```2. 出栈(pop)弹出栈顶元素,并返回该元素。

Java代码示例:```public E pop() {if (size == 0)throw new EmptyStackException();E result = elements[--size];elements[size] = null; // 避免内存泄漏 return result;}```3. 查看栈顶元素(peek)返回当前栈顶元素,但不弹出该元素。

Java代码示例:```public E peek() {if (size == 0)throw new EmptyStackException(); return elements[size - 1];}```4. 判断是否为空(isEmpty)判断当前栈是否为空。

栈的应用实验报告心得

栈的应用实验报告心得

栈的应用实验报告心得栈的应用实验报告心得一、引言栈(Stack)是一种常用的数据结构,具有先进后出(Last In First Out,简称LIFO)的特点。

在实际应用中,栈有着广泛的应用,例如函数调用、递归、表达式求值、括号匹配等。

为了更好地理解栈的应用,我们进行了一系列实验。

二、实验目的理解栈的基本概念和特点;掌握栈的基本操作,包括入栈、出栈、判空、读栈顶等;熟悉栈的应用场景,如逆波兰表达式求值、中缀表达式转后缀表达式等。

三、实验内容实现栈的基本操作:入栈、出栈、判空、读栈顶;实现逆波兰表达式求值算法;实现中缀表达式转后缀表达式算法;运用栈解决实际问题,如括号匹配等。

四、实验步骤及结果实验步骤(1)根据实验要求,设计栈的数据结构,并实现基本操作;(2)实现逆波兰表达式求值算法,通过入栈、出栈操作进行运算;(3)实现中缀表达式转后缀表达式算法,通过栈的特性进行转换;(4)运用栈解决括号匹配问题,通过入栈、出栈操作进行判断。

实验结果通过实验,我们成功实现了栈的基本操作,并运用栈解决了逆波兰表达式求值、中缀表达式转后缀表达式以及括号匹配等问题。

实验结果表明,栈在解决这些问题上具有很好的效果和应用价值。

五、实验心得通过本次实验,我对栈的概念和特点有了更深入的理解。

栈的先进后出特点使得其在很多实际问题中具有很好的应用场景。

在实现栈的过程中,我学会了如何设计栈的数据结构,并实现其基本操作。

通过实现逆波兰表达式求值算法和中缀表达式转后缀表达式算法,我进一步加深了对栈的理解,并熟悉了栈在算法中的应用。

同时,通过解决括号匹配问题,我认识到栈在实际问题中的实用性和重要性。

在实验过程中,我遇到了一些困难,如算法的设计和实现过程中的错误,以及对栈操作的理解等。

但通过努力和与同学的讨论,我逐渐克服了这些困难,并取得了较好的实验结果。

这次实验让我深刻认识到了理论与实践的关系,只有通过实际操作,才能更好地理解和应用理论知识。

基于栈结构的中缀表达式求值

基于栈结构的中缀表达式求值

实验三基于栈结构的中缀表达式求值班级:计科131、问题描述从键盘输入一中缀表达式字符串,读字符串,利用栈结构实现表达式求值。

2、输入与输出输入:从键盘中缀表达式如: 32+5×(6-4)输出:计算结果423、需求分析1.定义两个栈结构,数栈用于存放表达式中的数,符号栈用于存放表达式中的符号,实现栈的运算2.在读数的时候考虑多位运算3.实现表达式求值4、开发工具与环境硬件设备:微型计算机系统软件环境:操作系统Windows,开发工具等等5、概要设计1.结构定义typedef struct /* 运算符栈 */{ char *base,*top;int stacksize;}SqStack;typedef struct /* 运算数栈 */{ int *base,*top;int stacksize;}SqStack1;int priority[7][7]={{'>', '>', '<', '<', '<', '>', '>'}, // +{'>', '>', '<', '<', '<', '>', '>'}, // -{'>', '>', '>', '>', '<', '>', '>'}, // *{'>', '>', '>', '>', '<', '>', '>'}, // /{'<', '<', '<', '<', '<', '=', }, // ({'>', '>', '>', '>', ' ', '>', '>'}, // ){'<', '<', '<', '<', '<', ' ', '='} // #};/*用于比较符号优先级的全局二维数组*/2.各函数模块void InitStack(SqStack *s);操作结果:初始化运算符栈。

栈的应用——表达式求值

栈的应用——表达式求值

栈的应⽤——表达式求值 表达式求值是程序设计语⾔编译中的⼀个基本问题,它的实现就是对“栈”的典型应⽤。

本⽂针对表达式求值使⽤的是最简单直观的算法“算符优先法”。

本⽂给出两种⽅式来实现表达式求值,⽅式⼀直接利⽤中缀表达式求值,需要⽤到两个栈,操作数栈和操作符栈。

⾸先置操作数栈为空栈,操作符栈仅有“#”⼀个元素。

依次读⼊表达式中的每个字符,若是操作数则进操作数栈,若是操作符则和操作符栈的栈顶运算符⽐较优先权作相应操作,直⾄整个表达式求值完毕。

⽅式⼆⾸先把中缀表达式转换为后缀表达式并存储起来,然后利⽤读出的后缀表达式完成求值,其本质上是⽅式⼀的分解过程。

表达式求值的代码如下:#include <iostream>#include "stack"#include "map"using namespace std;/* 只能求⼀位整数的加减乘除混合运算 */map<char, pair<int, int>> priority; // 存放各个操作符的栈内栈外优先级,first是栈内,second是栈外char infix[50]; // 存放初始的中缀表达式char postfix[50]; // 存放转化的后缀表达式int result;void MakePriority() // 构造运算符优先级表{priority.insert(make_pair('#', make_pair(0, 0))); // isp(#)=0, icp(#)=0priority.insert(make_pair('\n', make_pair(0, 0))); // isp(\n)=0, icp(\n)=0 表达式结尾的'#'⽤'\n'代替,这样可以省略表达式末尾的结束符'#'priority.insert(make_pair('(', make_pair(1, 6))); // isp(()=1, icp(()=6priority.insert(make_pair('*', make_pair(5, 4))); // isp(*)=5, icp(*)=4priority.insert(make_pair('/', make_pair(5, 4))); // isp(/)=5, icp(/)=4priority.insert(make_pair('%', make_pair(5, 4))); // isp(%)=5, icp(%)=4priority.insert(make_pair('+', make_pair(3, 2))); // isp(+)=3, icp(+)=2priority.insert(make_pair('-', make_pair(3, 2))); // isp(-)=3, icp(-)=2priority.insert(make_pair(')', make_pair(6, 1))); // isp())=6, icp())=1}void InfixToPostfix() // 把中缀表达式转换为后缀表达式{int i = 0;stack<char> optrStack; // 操作符栈char optr; // optr为栈顶的操作符optrStack.push('#');while (!optrStack.empty()){if (isdigit(infix[i])) // 是操作数则直接输出(追加到postfix结尾){postfix[strlen(postfix)] = infix[i];postfix[strlen(postfix) + 1] = '\0';i++; // 读⼊中缀表达式的下⼀个字符}else// 是操作符, ⽐较优先级{optr = optrStack.top(); // 取出栈顶操作符if (priority[infix[i]].second > priority[optr].first) // icp(infix[i]) > isp(optr),infix[i]⼊栈{optrStack.push(infix[i]);i++;}else if (priority[infix[i]].second < priority[optr].first)// icp(infix[i]) < isp(optr),optr退栈并输出{postfix[strlen(postfix)] = optr;postfix[strlen(postfix) + 1] = '\0';optrStack.pop();}else// icp(infix[i]) = isp(optr),退栈但不输出,若退出的是'(',则继续读⼊下⼀个字符{optrStack.pop();if (optr == '(')i++;}}}}void CalculateByPostfix() // 通过后缀表达式求值{int i = 0;stack<int> opndStack; // 操作数栈int left, right; // 左右操作数int value; // 中间结果int newOpnd;while (postfix[i] != '#' && i < strlen(postfix)){switch (postfix[i]){case'+':right = opndStack.top(); // 从操作数栈中取出两个操作数opndStack.pop();left = opndStack.top();opndStack.pop();value = left + right;opndStack.push(value); // 中间结果⼊栈break;case'-':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();value = left - right;opndStack.push(value);break;case'*':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();value = left * right;opndStack.push(value);break;case'/':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();if (right == 0){cerr << "Divide by 0!" << endl;}else{value = left / right;opndStack.push(value);}break;default:newOpnd = (int)(postfix[i] - 48); // 操作数直接⼊栈opndStack.push(newOpnd);break;}i++;}result = opndStack.top();}void CalculateByInfix() // 直接利⽤中缀表达式求值{int i = 0;stack<char> optrStack; // 操作符栈stack<int> opndStack; // 操作数栈char optr; // optr为操作符栈顶的操作符int left, right, value; // 左右操作数以及中间结果optrStack.push('#');optr = optrStack.top();while (!optrStack.empty()) // 直到操作符栈为空{if (isdigit(infix[i])) // 是操作数, 进操作数栈{value = (int)(infix[i] - 48);opndStack.push(value);i++;}else// 是操作符, ⽐较优先级{optr = optrStack.top(); // 取出操作符栈顶的操作符if (priority[infix[i]].second > priority[optr].first) // icp(infix[i]) > isp(optr),infix[i]⼊栈 {optrStack.push(infix[i]);i++;}else if (priority[infix[i]].second < priority[optr].first) // icp(infix[i]) < isp(optr),optr退栈并输出{optrStack.pop();right = opndStack.top(); // 从操作数栈中取出两个操作数opndStack.pop();left = opndStack.top();opndStack.pop();switch (optr){case'+':value = left + right;opndStack.push(value); // 中间结果⼊栈break;case'-':value = left - right;opndStack.push(value); // 中间结果⼊栈break;case'*':value = left * right;opndStack.push(value); // 中间结果⼊栈break;case'/':if (right == 0){cerr << "Divide by 0!" << endl;}else{value = left / right;opndStack.push(value);}break;default:break;}}else{optrStack.pop();if (optr == '(')i++;}}}result = opndStack.top();}int main(){MakePriority(); // 构造运算符优先级表cout << "请输⼊中缀表达式:";cin >> infix;cout << "直接利⽤中缀表达式求值为:";CalculateByInfix();cout << result << endl;cout << "转化为后缀表达式:";InfixToPostfix();for (int i = 0;i < strlen(postfix);i++){cout << postfix[i];}cout << endl;cout << "利⽤后缀表达式求值为:";CalculateByPostfix();cout << result << endl;return0;} 为了⽅便起见,本⽂只是简单的设计了⼀个针对⼀位整数的四则运算进⾏求值的算法,对于处理多位整数的四则运算,需要对本⽂接受输⼊的数据类型进⾏“升阶”,把字符数组换成字符串数组,将⼀个整数的多位数字存⼊⼀个字符串进⾏处理。

栈的应用表达式求值的原理

栈的应用表达式求值的原理

栈的应用:表达式求值的原理一、栈的基本原理1.栈是一种具有特殊操作的线性数据结构。

2.栈的特点是后进先出(LIFO,Last In First Out)的存取方式。

3.栈有两个基本操作:入栈和出栈。

二、表达式求值的概念1.表达式是由运算符和运算对象组成的序列。

2.表达式求值是指根据运算符的优先级和结合性来计算表达式的值。

三、中缀表达式与后缀表达式1.中缀表达式:运算符位于运算对象的中间。

–例如:2 + 32.后缀表达式(逆波兰表达式):运算符位于运算对象的后面。

–例如:2 3 +四、中缀转后缀表达式1.利用栈实现中缀表达式到后缀表达式的转换。

2.遍历中缀表达式中的每个字符,若为数字,则输出到后缀表达式中;若为运算符,则根据优先级进行处理。

3.将运算符入栈,直到出现低优先级的运算符或左括号。

4.遇到右括号时,将栈中的运算符出栈并输出,直到遇到左括号。

5.将剩余的运算符出栈并输出。

五、后缀表达式求值1.利用栈实现后缀表达式的求值。

2.遍历后缀表达式中的每个字符,若为数字,则入栈;若为运算符,则弹出栈中的两个数字进行计算,并将结果入栈。

3.最后栈中的唯一元素即为表达式的求值结果。

六、示例假设要求解的中缀表达式为:2 + 3 * 4 - 5 1. 将中缀表达式转换为后缀表达式:2 3 4 * + 5 - 2. 根据后缀表达式求值的原则,遍历后缀表达式进行计算: - 遇到数字2,入栈; - 遇到数字3,入栈; - 遇到运算符*,弹出栈中的两个数字3和2进行计算得到6,并将结果入栈; - 遇到运算符+,弹出栈中的两个数字6和4进行计算得到10,并将结果入栈; - 遇到数字5,入栈; - 遇到运算符-,弹出栈中的两个数字10和5进行计算得到5,并将结果入栈。

3. 栈中的唯一元素5即为表达式的求值结果。

七、总结1.栈的应用在表达式求值中起到关键作用。

2.利用栈可以将中缀表达式转换为后缀表达式,并通过对后缀表达式的求值获得最终结果。

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告算术表达式求值实验报告一、引言算术表达式求值是计算机科学中一个重要的基础问题,它涉及到了数据结构和算法的应用。

本实验旨在通过实现一个算术表达式求值的程序,加深对数据结构中栈的理解和应用,并掌握算术表达式的求值过程。

二、实验目的1. 理解算术表达式的基本概念和求值过程;2. 掌握栈的基本操作和应用;3. 实现一个能够正确求解算术表达式的程序;4. 进一步熟悉编程语言的使用。

三、实验内容1. 设计并实现一个栈的数据结构;2. 实现算术表达式求值的算法;3. 编写测试用例,验证程序的正确性;4. 进行性能测试,分析算法的时间复杂度。

四、实验方法与步骤1. 设计栈的数据结构在本实验中,我们选择使用数组来实现栈的数据结构。

栈的基本操作包括入栈(push)、出栈(pop)、判断栈空(isEmpty)和获取栈顶元素(top)等。

2. 算术表达式求值算法算术表达式求值的一种常用算法是通过后缀表达式进行求值。

具体步骤如下: - 将中缀表达式转换为后缀表达式;- 通过栈来求解后缀表达式;- 返回最终的计算结果。

3. 编写测试用例编写一系列测试用例,包括不同类型的算术表达式,以验证程序的正确性。

例如:- 简单的四则运算表达式:2 + 3 * 4 - 5;- 包含括号的表达式:(2 + 3) * (4 - 5);- 包含多位数的表达式:12 + 34 * 56;- 包含浮点数的表达式:3.14 + 2.71828。

4. 性能测试和时间复杂度分析针对不同规模的输入数据,进行性能测试,记录程序的运行时间。

同时,分析算法的时间复杂度,验证算法的效率。

五、实验结果与分析我们设计并实现了一个栈的数据结构,并成功地完成了算术表达式求值的程序。

通过对一系列测试用例的验证,我们发现程序能够正确地求解各种类型的算术表达式,并返回正确的计算结果。

在性能测试中,我们对不同规模的输入数据进行了测试,并记录了程序的运行时间。

第3章 限定性线性表——栈和队列

第3章  限定性线性表——栈和队列

两栈共享技术(双端栈):
主要利用了栈“栈底位置不变,而栈顶位置动态变
化”的特性。首先为两个栈申请一个共享的一维数 组空间S[M],将两个栈的栈底分别放在一维数组的 两端,分别是0,M-1。
共享栈的空间示意为:top[0]和top[1]分别为两个 栈顶指示器 。
Stack:0
M-1
top[0]
top[1]
(1)第i号栈的进栈操作 int pushi(LinkStack top[M], int i, StackElementType x) { /*将元素x进入第i号链栈*/
LinkStackNode *temp; temp=(LinkStackNode * )malloc(sizeof(LinkStackNode)); if(temp==NULL) return(FALSE); /* 申请空间失败 */ temp->data=x; temp->next=top[i]->next; top[i]->next=temp; /* 修改当前栈顶指针 */ return(TRUE); }
case 1:if(S->top[1]==M) return(FALSE);
*x=S->Stack[S->top[1]];S->top[1]++;break;
default: return(FALSE);
}
return(TRUE);
返回主目录
}
【思考题】
说明读栈顶与退栈顶的处理异同,并标明将已知 的退栈顶算法改为读栈顶算法时应做哪些改动。
返回主目录
链栈的进栈操作
int Push(LinkStack top, StackElementType x)

栈和队列区别及应用场景

栈和队列区别及应用场景

栈和队列区别及应用场景栈(Stack)和队列(Queue)是两种常见的数据结构,它们在计算机科学领域有广泛的应用。

本文将从定义、特点和基本操作等方面详细介绍栈和队列的区别,并分析它们各自的应用场景。

一、栈的定义及特点:栈是一种线性数据结构,其特点是“先进后出”(Last In First Out,LIFO)。

即在栈中最后一个进入的元素,也是第一个出栈的元素。

栈的基本操作包括入栈和出栈。

入栈(Push)是将一个元素追加到栈的顶部,出栈(Pop)是将栈顶元素移除。

栈的应用场景:1.函数调用:在函数调用时,每遇到一个新的函数调用就将当前的上下文(包括局部变量和返回地址)压入栈中,当函数调用完毕后,再弹出栈顶元素,恢复上一个函数的上下文。

2.表达式求值:栈可以用于进行中缀表达式到后缀表达式的转换,并通过栈来计算后缀表达式的值。

3.递归:递归算法的实现中通常会使用栈来保存递归调用的上下文。

4.撤销操作:在很多应用程序中,比如文本编辑器和图像处理软件中,通过栈来存储用户操作,以便可以撤销之前的操作。

5.浏览器历史记录:浏览器通常使用栈来实现历史记录的功能,每当用户浏览一个新的页面时,就将该页面的URL入栈,当用户点击后退按钮时,再依次出栈。

6.二叉树的遍历:用栈可以实现二叉树的深度优先遍历,具体的实现是使用非递归的方式进行前序、中序、后序遍历。

二、队列的定义及特点:队列也是一种线性数据结构,其特点是“先进先出”(First In First Out,FIFO)。

即在队列中最先进入的元素,也是第一个出队列的元素。

队列的基本操作包括入队和出队。

入队(Enqueue)是将元素放入队列的尾部,出队(Dequeue)是将队列的头部元素移除。

队列的应用场景:1.广度优先搜索:在图论中,广度优先搜索(Breadth First Search,BFS)通常会使用队列来实现,按照层次的顺序进行搜索。

2.缓冲区:队列可以用作缓冲区,在生产者和消费者模型中,生产者将数据放入队列的尾部,消费者从队列的头部取出数据进行处理。

栈实现表达式的简单求值

栈实现表达式的简单求值

利用栈编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。

要求输出表达式的值此题目可选做。

注意:计算的结果数值不可以大于79.#include<stdio.h>#include<malloc.h>#define OK 1#define ERROR 0#define STACK_INIT_SIZE 100 // 存储空间初始分配量typedef struct{char *base;char *top;int stacksize;}Stack;int InitStack(Stack &S){S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char)); if(!S.base) return ERROR;S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}int Pop(Stack &S,char &e){if(S.top==S.base) return ERROR;e=*--S.top;return OK;}int GetTop(Stack S,char &e){if(S.top==S.base) return ERROR;e=*--S.top;return OK;}int Push(Stack &S,char ch){if(S.top-S.base>=S.stacksize){S.base=(char*)realloc(S.base,(S.stacksize+10)*sizeof(char)); if(!S.base) return ERROR;S.top=S.base+S.stacksize;S.stacksize+=10;}*S.top++=ch;return OK;}char Compare(char &e,char ch){switch(e){case '+':if(ch=='+'||ch=='-'||ch==')') return '>';else return '<';break;case '-':if(ch=='+'||ch=='-'||ch==')') return '>';else return '<';break;case '*':if(ch=='(')return '<';else return '>';break;case '/':if(ch=='(')return '<';else return '>';break;case '(':if(ch==')')return '=';else return '<';break;case ')':return '>';break;}}int Cal(char a,char theta,char b) {int s;a-=48;b-=48;switch(theta){case '+':s=a+b;break;case '-':s=a-b;break;case '*':s=a*b;break;case '/':s=a/b;break;}return s;}int StackEmpty(Stack S){if(S.top==S.base) return OK; return ERROR;}int Operator(){Stack CS;Stack NS;char ch,e;char a,b,theta;InitStack(CS);InitStack(NS);//Push(CS,'=');ch=getchar();while(ch!='='){if(ch>='0'&&ch<='9'){Push(NS,ch);ch=getchar();if(ch>='0'&&ch<='9'){Pop(NS,a);Push(NS,((a-48)*10+(ch-48))+48); ch=getchar();}}else{if(StackEmpty(CS)){Push(CS,ch);ch=getchar(); continue;}GetTop(CS,e);switch(Compare(e,ch)) {case '<':Push(CS,ch); ch=getchar();break;case '=':Pop(CS,e);ch=getchar();break;case '>':Pop(CS,theta);Pop(NS,a);Pop(NS,b);Push(NS,Cal(b,theta,a)+48); break;}}}while(Pop(CS,theta)){Pop(NS,a);Pop(NS,b);Push(NS,(Cal(b,theta,a)+48)); }GetTop(NS,ch);return (ch-48);}int main(){printf("%d\n",Operator()); return 0;}输入格式第一行:一个算术表达式输出格式第一行:算术表达式的值输入样例3*(9-7)=(0-12)*((5-3)*3)/(2+2)=输出样例6-18。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<malloc.h>#include<limits.h>#include<io.h>#include<math.h>#include<process.h>//函数结果状态代码#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define Stack_Init_Size 10#define StackIncrement 2//#define OVERFLOW -1 //在math.h 中已定义OVERFLOW 等于3typedef int Status;typedef int Boolean;typedef int SElemType;typedef struct sqstack//结构体{SElemType * base ;SElemType * top ;int stacksize ;//栈的大小}SqStack,*PSqStack;Status Init(SqStack &S){//初始化栈S.base = (SElemType *)malloc(Stack_Init_Size * sizeof(SElemType));if (!S.base) exit(OVERFLOW);//存分配不足S.top = S.base;//栈为空S.stacksize = Stack_Init_Size ;return OK;}Status DestoryStack(SqStack &S){//销毁栈free(S.base);S.base = NULL;//预防野指针的出现S.top = NULL;//预防野指针的出现S.stacksize = 0;return OK;}Status StackEmpty(SqStack S){//判断栈是否为空,若空返回TRUE 否则返回FALSEif (S.base == S.top)return TRUE ;elsereturn FALSE ;}Status StackClear(SqStack &S){//清空栈S.top = S.base;return OK;}Status GetTop(SqStack S,SElemType &e){//若栈不为空,则e返回栈顶元素的值,返回值为OK,否则返回值为ERROR if (S.top == S.base) return ERROR;e=*(S.top-1);return OK;}Status Push(SqStack &S,SElemType e){//入栈操操作,入栈元素为eif(S.top-S.base >= S.stacksize)//栈满了的时候{S.base = (SElemType *)realloc(S.base,(S.stacksize+StackIncrement)*sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base + S.stacksize;S.stacksize = S.stacksize+StackIncrement;}*(S.top) = e;//栈没满的时候S.top++;return OK;}Status Pop(SqStack &S,SElemType &e){//若栈不空,则删除栈顶元素,用e返回,返回值为OK,否则返回ERRORif(S.top == S.base) return ERROR;S.top--;//top里面没元素e = *(S.top);}void StackTraverse(SqStack S){SElemType * p=S.top-1;// if(S.top == S.base) ;while(p >= S.base){printf("%d ",*p);p--;}}//以上是栈的基本操作//下面的是对表达式的基本操作char Precede(SElemType t1, SElemType t2){//判断t1,t2的优先级('#'代替'\n'),t1、t2是两个运算符char f;switch(t2){case'+':case'-':if(t1 == '(' || t1 == '\n')f ='<';//t1<t2elsef ='>';//t1>t2break;case'*':case'/':if(t1 == '*' || t1 == '/' || t1 == ')')f ='>';//t1>t2elsef ='<';//t1<t2break;case'(':if(t1 == ')'){printf("括号不匹配\n");exit(ERROR);}elsef ='<';//t1<t2break;case')':switch(t1){case'(':f ='=';//t1=t2break;case'\n':printf("缺乏左括号\n");exit(ERROR);default:f ='>';//t1>t2}break;case'\n':switch(t1){case'\n':f ='=';break;case'(':printf("缺乏右括号\n");exit(ERROR);default:f ='>';}}return f;}Status In(SElemType c){//判断c是否为7种运算符之一switch(c){case'+':case'-':case'*':case'/':case'(':case')':case'\n':return TRUE;default:return FALSE;}}SElemType Operate(SElemType a,SElemType theta,SElemType b){//做四则运算a theta b,返回运算结果switch(theta){case'+':return a+b;case'-':return a-b;case'*':return a*b;case'/':return a/b;}}SElemType EvaluateExpression(){//算数表达式求值的算符优先算法。

设OPTR和OPND分别为运算符栈和数字栈SqStack OPTR,OPND;SElemType a,b,c,x;Init(OPTR);Init(OPND);Push(OPTR,'\n');c = getchar();GetTop(OPTR,x);while(c != '\n' || x !='\n'){if(In(c))switch(Precede(x,c)){case'<':Push(OPTR,c);c = getchar();break;case'=':Pop(OPTR,x);c = getchar();break;case'>':Pop(OPTR,x);Pop(OPND,b);Pop(OPND,a);Push(OPND,Operate(a,x,b));}else if(c >= '0' && c <= '9')//c是操作数{Push(OPND,c-48);c = getchar();}else{printf("出现非法字符!\n");exit(ERROR);}GetTop(OPTR,x);}Pop(OPND,x);//弹出运算数栈OPND的栈顶元素给x if(!StackEmpty(OPND)){printf("表达式不正确\n");exit(ERROR);}return x;}int main(){printf("请输入算数表达式(输入的值要在0~9之间,中间运算以及输出结果在-1287~127之间)\n");printf("%d\n",EvaluateExpression());system("pause");return 0;}。

相关文档
最新文档