利用栈求表达式的值

合集下载

考研计算机学科专业基础综合-25_真题-无答案

考研计算机学科专业基础综合-25_真题-无答案

考研计算机学科专业基础综合-25(总分80,考试时间90分钟)一、单项选择题在每小题给出的四个选项中,请选出一项最符合题目要求的。

1. 设n是描述问题规模的非负整数,下面程序片段的时间复杂度是( )。

A.O(n2log2n) B.O(nlog5n) C.O(n2log5n) D.O(n3)2. 利用栈求表达式的值时,设立运算数栈OPND。

假设OPND只有两个存储单元,在下列表达式中,不发生溢出的是( )。

A.A—B*(C—D) B.(A—B)*C—DC.(A—B*C)—D D.(A—B)*(C—D)3. 已知输入序列为abcd,经过输出受限的双端队列后,能得到的输出序列是( )。

A.dacb B.cadbC.dbca D.以上答案都不对4. 一个具有1025个结点的二叉树的高度为( )。

A.11 B.10C.11至1025之间 D.10至1024之间5. 以下关于二叉排序树的说法正确的是( )。

Ⅰ在二叉排序树中,每个结点的关键字都比左孩子关键字大,比右孩子关键字小Ⅱ每个结点的关键字都比左孩子关键字大,比右孩子关键字小,这样的二叉树都是二又排序树Ⅲ在二叉排序树中,新插入的关键字总是处于最底层Ⅳ在二叉排序树中,新结点总是作为叶子结点来插入的Ⅴ二叉排序树的查找效率和二叉排序树的高度有关A.Ⅰ、Ⅱ、Ⅳ、Ⅴ B.Ⅱ、Ⅲ、Ⅳ C.Ⅰ、Ⅲ、Ⅴ D.Ⅰ、Ⅳ、Ⅴ6. 简单无向图的邻接矩阵是对称的,可以对其进行压缩存储。

若无向图G有n个结点,其邻接矩阵为A[1..n,1..n],且压缩存储在B[1..k],则k的值至少为( )。

A.n(n+1)/2 B.n2/2C.(n-1)(n+1)/2 D.n(n-1)/27. 若无向图G=(V,E)中含8个顶点,为保证图G在任何情况下都是连通的,则需要的边数最少是( )。

A.7 B.21 C.22 D.288. 用递归算法实现n个不同元素的有序序列的折半查找,采用一个递归工作栈时,该栈的最小容量应为( )。

数据结构-表达式求值

数据结构-表达式求值

数据结构:线性结构—栈实现表达式求值一.问题分析利用栈这种数据结构存储数字和运算符,并实现表达式求值。

为实现按运算符优先顺序进行计算,需要在执行程序的过程中对运算符的优先顺序做出判断。

利用栈先进后出的特点,同时保证优先级最高的运算符始终在栈顶。

当栈顶元素优先级低于读入的运算符时,将该栈顶运算符推出。

这就保证了优先级高的运算符先计算。

二.数据结构—栈1.优先关系表:prior[7][7]={// +-*/()#'>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>','>','<','>','>','>','>','>','>','<','>','>','<','<','<','<','<','=',' ','>','>','<','>',' ','>','>','<','<','<','<','<',' ','='};将关系表直接用字符型的二维数组存储。

计算机408统考真题

计算机408统考真题

计算机专业基础综合考试模拟试卷(一)一、单项选择题:第1~40小题,每小题2分,共80分。

下列每题给出的四个选项中,只有一个选项最符合试题要求。

1.已知一个栈的进栈序列是1、2、3、…、n,其输出序列为p1、p2、p3、…、p n,若p1=3,则p2为()。

A.2或4、5、…、n都有可能B.可能是1C.一定是2 D.只可能是2或4 2.利用栈求表达式的值时,设立运算数栈OPEN。

假设OPEN只有两个存储单元,则在下列表达式中,不会发生溢出的是()。

A.A−B*(C−D) B.(A−B)*C−D C.(A−B*C)−DD.(A−B)*(C−D)3.已知A[1…N]是一棵顺序存储的完全二叉树,9号结点和11号结点共同的祖先是()。

A.4 B.6 C.2D.84.在常用的描述二叉排序树的存储结构中,关键字值最大的结点是()。

A.左指针一定为空B.右指针一定为空C.左、右指针均为空D.左、右指针均不为空5.分别以下列序列构造二叉排序树,与用其他三个序列所构造的结果不同的是()。

A.(100,80, 90,60,120,110,130)B.(100,120,110,130,80,60,90)C.(100,60,80,90,120,110,130)D.(100,80, 60,90,120,130,110)6.设无向图G=(V,E)和G′=(V′,E′),如果G′是G的生成树,则下面说法错误的是()。

A.G′是G的子图B.G′是G的连通分量C.G′是G的极小连通子图且V=V′D.G′是G的一个无环子图7.若G是一个具有36条边的非连通无向简单图,则图G的结点数至少是()。

A.11 B.10 C.9D.88.在有向图G的拓扑序列中,若顶点V i在顶点V j之前,则下列情形不可能出现的是()。

A.G中有弧<V i,V j> B.G中有一条从V i到V j的路径C.G中没有弧< V i,V j> D.G中有一条从V j到V i的路径9.具有12个关键字的有序表中,对每个关键字的查找概率相同,折半查找查找成功和查找失败的平均查找长度依次为()。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

一、算法思路首先,我们需要明确一个重要概念——逆波兰表达式(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)。

栈和队列的应用实例

栈和队列的应用实例

栈和队列的应用实例栈和队列都是常用的数据结构,在计算机科学中有着广泛的应用。

以下是一些常见的应用实例:1. 栈的应用实例●表达式求值:使用栈可以方便地对表达式进行求值,如逆波兰表达式求值。

●函数调用:函数调用时,每当进入一个函数,都会将上一个函数的现场信息压入栈中,然后在函数返回时再将其弹出,以便恢复上一个函数的执行现场。

●括号匹配:使用栈可以很方便地检查输入序列中括号的匹配情况。

2. 队列的应用实例●广度优先搜索:在图中进行广度优先搜索时常使用队列,因为它满足“先进先出”的特点,可以确保搜索的顺序是按层次来进行的。

●消息队列:在分布式系统中,消息队列经常用于实现进程之间的通信,以及任务的异步处理。

●缓冲区:在计算机中,经常需要通过使用缓冲区来平衡生产者和消费者之间的速度差异,队列就是一种常用的缓冲区实现方式。

以下是具体的应用实例:栈逆波兰表达式求值逆波兰表达式是一种不需要括号的算术表达式表示方法,它将运算符写在操作数的后面,因此也被称为“后缀表达式”。

例如,中缀表达式“3 + 4 * 2 / (1 - 5)”的逆波兰表达式为“3 4 2 * 1 5 - / +”。

逆波兰表达式求值时,可以使用栈来存储数字和运算符,具体过程如下:1. 遍历逆波兰表达式中的每个元素。

2. 如果当前元素是数字,则压入栈中。

3. 如果当前元素是运算符,则从栈中弹出两个操作数进行运算,并将结果压入栈中。

4. 遍历完逆波兰表达式后,栈顶即为表达式的值。

以下是Python语言实现逆波兰表达式求值的代码:def evalRPN(tokens: List[str]) -> int:stack = []for token in tokens:if token in '+-*/': # 运算符num2 = stack.pop()num1 = stack.pop()if token == '+':stack.append(num1 + num2)elif token == '-':stack.append(num1 - num2)elif token == '*':stack.append(num1 * num2)else:stack.append(int(num1 / num2))else: # 数字stack.append(int(token))return stack[0]该函数接受一个字符串列表tokens,其中包含了逆波兰表达式的所有元素。

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

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

实验三基于栈结构的中缀表达式求值班级:计科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;} 为了⽅便起见,本⽂只是简单的设计了⼀个针对⼀位整数的四则运算进⾏求值的算法,对于处理多位整数的四则运算,需要对本⽂接受输⼊的数据类型进⾏“升阶”,把字符数组换成字符串数组,将⼀个整数的多位数字存⼊⼀个字符串进⾏处理。

用栈解决表达式求值问题的c语言代码

用栈解决表达式求值问题的c语言代码

栈是一种常见的数据结构,用于解决许多算法和数据处理问题。

在编程中,栈通常用于处理表达式求值问题。

本篇文章将介绍如何使用栈解决表达式求值问题,并给出对应的C语言代码。

1. 表达式求值问题介绍表达式求值是指计算一个数学表达式的值,通常涉及到四则运算、括号和优先级等概念。

给定一个表达式“3 + 4 * 2”,我们需要得到其计算结果为11。

在编程中,需要将该表达式转换为计算机可识别的形式,并使用算法进行求值。

2. 中缀表达式、前缀表达式和后缀表达式在计算机中常见的表达式有三种形式:中缀表达式、前缀表达式和后缀表达式。

其中,中缀表达式是通常人们在日常生活中使用的表达式形式,如“3 + 4 * 2”。

前缀表达式是运算符位于操作数之前的形式,例如“+ 3 * 4 2”。

后缀表达式则是运算符位于操作数之后的形式,例如“3 4 2 * +”。

3. 使用栈解决表达式求值问题在解决表达式求值问题时,我们可以利用栈的特性来简化计算过程。

具体步骤如下:3.1 将中缀表达式转换为后缀表达式我们需要将中缀表达式转换为后缀表达式,这样可以简化表达式的计算顺序。

具体转换规则如下:- 从左至右扫描中缀表达式的每个数字或符号。

- 如果是操作数,则直接输出。

- 如果是运算符,则弹出栈中所有优先级大于或等于该运算符的运算符,并将其压入栈中,然后压入该运算符。

- 如果是括号,则根据括号的不同情况进行处理。

通过以上规则,我们可以将中缀表达式转换为后缀表达式。

3.2 计算后缀表达式的值得到后缀表达式后,我们可以利用栈来计算其值。

具体步骤如下:- 从左至右扫描后缀表达式的每个数字或符号。

- 如果是操作数,则压入栈中。

- 如果是运算符,则弹出栈中的两个操作数进行相应的运算,并将结果压入栈中。

- 继续扫描直到表达式结束,栈中的值即为所求结果。

通过以上步骤,我们可以使用栈来解决表达式求值问题。

4. C语言代码实现以下是使用C语言实现栈来解决表达式求值问题的代码示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct {int top;int capacity;int* array;} Stack;Stack* createStack(int capacity) {Stack* stack = (Stack*)malloc(sizeof(Stack));stack->capacity = capacity;stack->top = -1;stack->array = (int*)malloc(stack->capacity * sizeof(int)); return stack;}int isFull(Stack* stack) {return stack->top == stack->capacity - 1; }int isEmpty(Stack* stack) {return stack->top == -1;}void push(Stack* stack, int item) {if (isFull(stack)) return;stack->array[++stack->top] = item;}int pop(Stack* stack) {if (isEmpty(stack)) return -1;return stack->array[stack->top--];}int evaluatePostfix(char* exp) {Stack* stack = createStack(strlen(exp)); for (int i = 0; exp[i]; i++) {if (isdigit(exp[i])) {push(stack, exp[i] - '0');} else {int val1 = pop(stack);int val2 = pop(stack);switch (exp[i]) {case '+':push(stack, val2 + val1); break;case '-':push(stack, val2 - val1); break;case '*':push(stack, val2 * val1); break;case '/':push(stack, val2 / val1); break;}}}return pop(stack);}int m本人n() {char exp[] = "34*2+";printf("The value of s is d\n", exp, evaluatePostfix(exp));return 0;}```以上代码实现了栈的基本功能,并利用栈来计算后缀表达式的值。

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

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

栈的应用:表达式求值的原理一、栈的基本原理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 数据结构基础知识1.数据的逻辑结构是指(),数据的存储结构是指()分析:数据结构包括三方面的内容:数据的逻辑结构、存储结构和数据的运算。

其中,逻辑结构是指各数据元素之间的逻辑关系,存储结构是指逻辑结构用计算机语言的实现。

解答:数据元素之间的逻辑关系;数据的逻辑结构用计算机语言的实现。

2.在数据结构中,从逻辑上可以把数据结构分为:(A)A 线性和非线性结构B 紧凑和非紧凑结构C 动态和静态结构D 内部和外部结构分析:数据结构中,逻辑上可以把数据结构分成线性结构和非线性结构。

线性结构的顺序存储结构是一种随机存取的存储结构,线性表的链式存储结构是一种顺序存储结构。

线性表若采用链式存储表示时,所有结点之间的存储单元地址可连续可不连续。

逻辑结构与数据元素本身的形式、内容、相对位置、所含结点个数无关。

关键考点点评:线性结构的特征,有且仅有一个开始结点和终端结点,所有结点最多只有一个直接前驱和后继。

栈和队列。

非线性结构的结点有多个前驱或后继,树和图。

3.数据结构在物理上可以分为()存储结构和链式存储结构。

分析:物理存储解答:顺序4.下列术语中,()与数据的存储结构无关A 循环队列B 堆栈C 散列表D 单链表解答: A5.()不是算法所必须具备的特性A 有穷性B 确定性C 高效性D 可行性分析:算法的五个重要特征:有穷性、确定性、可行性、输入和输出。

解答:C考点2 时间复杂度计算1.设n是描述问题规模的非负整数,下面程序段的时间复杂度是()2.第二章线性表考点1 线性表的基本概念1.线性表是n个()的有限序列。

A 字符B数据元素 C 由数据项 D 信息项解析:解答 B2.线性表是一个()。

A 有限序列,可以为空B 有限序列,不能为空C 无限序列,可以为空D 无限序列,不能为空解答 A关键考点点评:对于非空线性表1.有且仅有一个开始结点,没有直接前驱,有且仅有一个直接后继;2.有且仅有一个终结结点,没有直接后继,有且仅有一个直接前驱;3.其余的内部结点都有且仅有一个直接前驱和后继3.单链表不能随机存取元素原因是:要得到元素的存储地址,必须()解答:从起始结点开始扫描以得到其地址注:顺序表可以,但是链表不行考点2 线性表的顺序存储结构1.下述()是顺序存储结构的优点A 插入运算方便B 可方便地用于各种逻辑结构的存储表示C 存储密度大D 删除运算方便解答: C2.线性表的()存储结构是随机存储结构。

利用栈进行表达式求值

利用栈进行表达式求值
myStack.base = (int *)realloc(myStack.base, (myStack.stacksize+STACKINCREMENT)*sizeof(int));
myStack.top = myStack.base + myStack.stacksize;
myStack.stacksize += STACKINCREMENT;
#include "Stdafx.h"
#include <stdio.h>
#include <malloc.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef struct {
int *base;
int *top;
int stacksize;
if(isNum(c)) {
push(opnd, ((int)c-48));
c = getchar();
} else {
switch(precede((char)getTop(oprt), c)) {
case '<' : push(oprt, c); c = getchar(); break;
case '=' : pop(oprt, t); c = getchar(); break;
default : return '>';
} break;
case '(' :
switch (c2) {
case ')' : return '='; break;

栈的应用实验报告

栈的应用实验报告

栈的应用实验报告栈的应用实验报告引言:栈是一种常见的数据结构,它具有后进先出(Last In First Out,LIFO)的特点。

在计算机科学中,栈被广泛应用于各种领域,如编译器、操作系统、图形处理等。

本实验旨在通过实际应用场景,探索栈的应用。

一、栈的基本概念和操作栈是一种线性数据结构,它由一系列元素组成,每个元素都有一个前驱元素和一个后继元素。

栈的基本操作包括入栈(Push)和出栈(Pop)。

入栈将元素添加到栈的顶部,而出栈则将栈顶元素移除。

此外,栈还具有查看栈顶元素(Top)和判断栈是否为空(IsEmpty)的操作。

二、栈在表达式求值中的应用栈在表达式求值中发挥着重要作用。

例如,当我们需要计算一个数学表达式时,可以通过将表达式转换为后缀表达式,并利用栈来进行求值。

栈中存储操作数,当遇到运算符时,从栈中弹出相应数量的操作数进行计算,再将结果入栈。

通过这种方式,我们可以实现高效的表达式求值。

三、栈在函数调用中的应用栈在函数调用中也扮演着重要角色。

当我们调用一个函数时,计算机会将函数的返回地址、参数和局部变量等信息存储在栈中。

这样,当函数执行完毕后,可以从栈中恢复之前的上下文,继续执行调用函数的代码。

栈的这种特性使得递归函数的实现成为可能,同时也为程序的模块化提供了便利。

四、栈在迷宫求解中的应用栈在迷宫求解中也能发挥重要作用。

当我们需要找到从起点到终点的路径时,可以利用栈来存储当前路径上的位置。

从起点开始,我们按照某种策略选择下一个位置,并将其入栈。

如果当前位置无法继续前进,则将其出栈,并选择下一个位置。

通过不断重复这个过程,直到找到终点或者栈为空,我们就能得到迷宫的解。

五、栈在撤销和恢复操作中的应用栈在撤销和恢复操作中也能发挥重要作用。

当我们在编辑文档或者绘图时,经常需要进行撤销和恢复操作。

栈可以用来记录每次操作的状态,当用户选择撤销时,从栈中弹出最近的操作,并将文档或图形恢复到之前的状态。

通过这种方式,我们可以提供良好的用户体验,同时也方便用户进行操作的回溯。

VB利用栈实现表达式求值

VB利用栈实现表达式求值

实验一Dim s(100) As String, t As IntegerPrivate Sub Command2_Click()Dim x As String, n, i As IntegerText3.Text = " "For i = t To 1 Step -1pop x, s(), tText3.Text = Text3.Text & xNext iEnd SubPrivate Sub Command1_Click()Dim a, b, x As String, n, i, m As IntegerText2.Text = ""a = Text1.Textn = Len(a)m = 10t = 0For i = 1 To nx = Mid(a, i, 1)PUSH x, s(), m, tText2.Text = Text2.Text & s(i)Next iEnd SubPublic Sub PUSH(x As String, s() As String, m As Integer, top As Integer)If (top = m) ThenMsgBox "数据有误"EndEnd Iftop = top + 1s(top) = x End SubPublic Sub pop(x, s() As String, top As Integer) If top = 0 ThenMsgBox "栈空"End Ifx = s(top)top = top - 1End SubPublic Sub pre(x As String, p As Integer)Select Case xCase "*"p = 2Case "+"p = 1Case "-"p = 1Case ";"p = 0Case "^"p = 3End SelectEnd SubPrivate Sub Command3_Click()Dim topo As Integer, topn As IntegerDim p, f, i, x1, y1 As IntegerDim a1 As Integer, a2 As IntegerDim y, os(100) As StringDim a As String, x As StringDim z As String, w As StringDim ns(100) As String, q As Stringtopo = 0topn = 0z = ";"f = 0PUSH z, os(), 10, topoi = 0a = Text1.TextDo While f <> 2If f = 0 Theni = i + 1w = Mid(a, i, 1)End IfIf Not ((w = "*") Or (w = "+") Or (w = "-") Or (w = "/") Or (w = "^") Or (w = ";")) ThenPUSH w, ns(), 10, topnElsetp q, os(), topopre w, a1pre q, a2If (a1 > a2) ThenPUSH w, os(), 10, topof = 0ElseIf (q = ";") And (w = ";") Thenpop x, ns(), topnf = 2Elsepop x, ns(), topnpop y, ns(), topnpop q, os(), topox1 = Val(x)y1 = Val(y) Select Case qCase "*"x1 = y1 * x1Case "/"x1 = y1 / x1Case "+"x1 = y1 + x1Case "-"x1 = y1 - x1Case "'"x1 = y1 ^ x1End Selectx = Str(x1)PUSH x, ns(), 10, topnf = 1End IfEnd IfLoopText4.Text = Str(x1)End SubPrivate Sub Form_Load()Text1.Text = ""Text2.Text = ""End SubPublic Sub tp(x, s() As String, top As Integer) If top = 0 ThenMsgBox "栈空"End Ifx = s(top)End Sub。

王道模拟试题(前3套)

王道模拟试题(前3套)

25. 设有 3 个作业,它们的到达时间和运行时间如下表所示,并在一台处理机上按单道方式运行。如按高 响应比优先算法,则作业执行的次序和平均周转时间依次为( 作业提交时间和运行时间表 作业号 1 2 3 A. J1,J2,J3、1.73 C. J1,J3,J2、2.08
int counter=6; P1: computing; counter=counter+1; P2: printing; counter=counter-2;
int A[50][50]; for(int i=0;i<50;i++) for(int j=0;j<50;j++) A[i][j]=0;
若在程序执行时内存只有一个存储块用来存放数组信息,则该程序执行时产生( A. 1 B. 50 C. 100 D. 2500 ) 。
)次缺页中断。
29. 若存储单元长度为 n,存放在该存储单元的程序长度为 m,则剩下长度为 n-m 的空间称为该单元的内 部碎片。下面存储分配方法中,哪种存在内部碎片( I. 固定式分区 II. 动态分区 IV. 段式管理 A. I 和 II B. I、III 和 V III. 页式管理 VI.请求段式管理 D. III 和 V ) 。 C. IV、V 和 VI V. 段页式管理
int n=0xA1B6; unsigned int m=n; m=m>>1; //m 右移一位
)时,x<-1/2 成立。
14. 设机器数字长 16 位,有一个 C 语言程序段如下:
则在执行完该段程序后,m 的值为( A. 50DBH B. FFB6H
) D. D0DBH ) 。 (假设不考虑一致维护位) D. 64× 13 bit ) 。

栈的应用实验报告

栈的应用实验报告

数据结构实验报告报告名称栈的应用专业网络工程班级1001学号************姓名张剑指导教师陈淑红李珍辉黄哲2012 年5 月4日一、实验目的:熟练掌握栈的基本操作,进一步理解栈的应用。

二、实验内容与基本要求:实验内容:设计一个程序,用算符优先法对算术表达式求值基本要求:以字符序列的形式从终端输入语法正确的、不含变量的算术表达式,利用算符优先关系,实现对算术四则混合运算表达式求值。

三、实现提示:1.利用栈辅助分析算符优先关系;2.在读入表达式字符序列的同时,完成运算符和操作数的识别处理,以及相应的运算;3.在识别出操作数的同时,要将其字符序列形式转换成相应的浮点数形式。

四.概要设计:1.顺序栈的定义:typedef struct{SElemType *base;SElemType *top;int stacksize;} SqStack;2.栈的基本操作:InitStack(&S)操作结果:构造一个空栈S。

DestoryStack(&S)初始条件:栈S存在。

、操作结果:栈S被销毁。

ClearStack(&S)初始条件:栈S存在。

、操作结果:将S清为空栈。

StackEmpty(&S)初始条件:栈S存在。

、操作结果:若S为空栈,则返回TUUE,否则FALSE.StackLength(&S)初始条件:栈S存在。

、操作结果:返回S的元素个数,即栈的长度。

GetTop(S,&e)初始条件:栈S存在且非空。

操作结果:用e 返回S的栈顶元素。

Push(&S,e)初始条件:栈S存在。

、操作结果:插入元素e为新的栈顶元素。

pop (&s,&e)初始条件:栈S存在且非空。

操作结果:删除S的栈顶元素,并用e返回其值。

StackTravse(S,vist())初始条件:栈S存在且非空.操作结果:从栈底到栈顶依次对S的每个元素调用函数vist(),一旦vist()失败,择操作结束。

考研计算机学科专业基础综合-48_真题-无答案

考研计算机学科专业基础综合-48_真题-无答案

考研计算机学科专业基础综合-48(总分151,考试时间90分钟)一、单项选择题1. 已知一个栈的进栈序列是1、2、3、…、n,其输出序列为p1、p2、p3、…、pn,若p1=3,则p2为______。

A. 2或4、5、…、n都有可能B. 可能是1C. 一定是2D. 只可能是2或42. 利用栈求表达式的值时,设立运算数栈OPEN。

假设OPEN只有两个存储单元,则在下列表达式中,不会发生溢出的是______。

A. A-B*(C-D)B. (A-B)*C-DC. (A-B*C)-DD. (A-B)*(C-D)3. 已知A[1...N]是一棵顺序存储的完全二叉树,9号结点和11号结点共同的祖先是______。

A. 4B. 6C. 2D. 84. 在常用的描述二叉排序树的存储结构中,关键字值最大的结点是______。

A. 左指针一定为空B. 右指针一定为空C. 左、右指针均为空D. 左、右指针均不为空5. 分别以下列序列构造二叉排序树,与用其他三个序列所构造的结果不同的是______。

A. (100,80,90,60,120,110,130)B. (100,120,110,130,80,60,90)C. (100,60,80,90,120,110,130)D. (100,80,60,90,120,130,110)6. 设无向图G=(V,E)和G"=(V",E"),如果G"是G的生成树,则下面说法错误的是______。

A. G"是G的子图B. G"是G的连通分量C. G"是G的极小连通子图且V=V",D. G"是G的一个无环子图7. 若G是一个具有36条边的非连通无向简单图,则图G的结点数至少是______。

A. 11B. 10C. 9D. 88. 在有向图G的拓扑序列中,若顶点Vi在顶点Vj之前,则下列情形不可能出现的是______。

计算机学科专业基础综合模拟1

计算机学科专业基础综合模拟1

[模拟] 计算机学科专业基础综合模拟1单项选择题第1题:利用栈求表达式的值时,设立运算数栈OPND。

假设OPND只有两个存储单元,在下列表达式中,不发生溢出的是( )。

A.A—B*(C—D)B.(A—B)*C—DC.(A—B*C)—DD.(A—B)*(C—D)参考答案:B第2题:已知输入序列为abcd,经过输出受限的双端队列后,能得到的输出序列是( )。

A.dacbB.cadbC.dbcaD.以上答案都不对参考答案:B输出受限的双端队列是指删除限制在一端进行,而插入允许在两端进行的队列。

分析选项A,输入序列为abcd,输出序列为dacb,由输出受限性质可知以da开头的结果只有dabc,选项A为错误答案。

分析选项B,输入序列为abcd,输出序列为cadb,其输入输出顺序为:先在输出端输入a,然后在非输出端输入b,这时队列中的序列为ba,再在输出端输入c,这时队列中的序列为bac:;输出c,再输出a;再在输出端输入d,这时队列中的序列为bd;输出d,再输出b。

最后得到输出序列为cadb。

分析选项C,输入序列为abcd,输出序列为dbca,由输出受限性质可知以db开头的结果只有dbad,选项C为错误答案。

第3题:一个具有1025个结点的二叉树的高度为( )。

A.11B.10C.11至1025之间D.10至1024之间参考答案:C一棵二叉树每层只有1个结点,则具有1025个结点的二叉树的最大高度为1025。

一个具有1025个结点的完全二叉树的高度为11。

这一个具有1025个结点的二叉树的高h为11至1025之间。

第4题:以下关于二叉排序树的说法正确的是( )。

Ⅰ在二叉排序树中,每个结点的关键字都比左孩子关键字大,比右孩子关键字小Ⅱ每个结点的关键字都比左孩子关键字大,比右孩子关键字小,这样的二叉树都是二又排序树Ⅲ在二叉排序树中,新插入的关键字总是处于最底层Ⅳ在二叉排序树中,新结点总是作为叶子结点来插入的Ⅴ二叉排序树的查找效率和二叉排序树的高度有关A.Ⅰ、Ⅱ、Ⅳ、ⅤB.Ⅱ、Ⅲ、ⅣC.Ⅰ、Ⅲ、ⅤD.Ⅰ、Ⅳ、Ⅴ参考答案:D对于二叉排序树,左子树上所有记录的关键字均小于根记录的关键字;右子树上所有记录的关键字均大于根记录的关键字。

栈实现表达式的简单求值

栈实现表达式的简单求值

利用栈编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(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)。

题目:利用栈求表达式的值一.设计任务和目标编写程序实现表达式求值,即验证某算术表达式的正确性,若正确,则计算该算术表达式的值。

主要功能描述如下:1、从键盘上输入表达式。

2、分析该表达式是否合法:(1)是数字,则判断该数字的合法性。

若合法,则压入数据到堆栈中。

(2)是规定的运算符,则根据规则进行处理。

在处理过程中,将计算该表达式的值。

(3)若是其它字符,则返回错误信息。

主要功能描述如下:1、从键盘上输入表达式。

2、分析该表达式是否合法:(1)是数字,则判断该数字的合法性。

若合法,则压入数据到堆栈中。

(2)是规定的运算符,则根据规则进行处理。

在处理过程中,将计算该表达式的值。

(3)若是其它字符,则返回错误信息。

程序应包括以下几个功能函数void initstack();初始化堆栈int Make_str();语法检查并计算int push_operate(int operate):将操作码压入堆栈int push_num(double num):将操作数压入堆栈int procede(int operate):处理操作码int change_opnd(int operate):将字符型操作码转换成优先级int push_opnd(int operate):将操作码压入堆栈int pop_opnd();将操作码弹出堆栈int caculate(interru_opnd):简单计算+,-,*,/double pop_num():弹出操作数程序如下:#include "stdio.h"#include "string.h"#include "stdlib.h"#define MAXLEN 100typedef struct{char op;int level;}opt;typedef struct //定义操作符栈{opt st[MAXLEN];int top;}op_stack;typedef struct //定义值栈{double D[MAXLEN];int top;}D_stack;//--------对栈操作的定义-------------opt peek(op_stack *s) //定义看栈顶函数{opt error=;if(s->top>=0)return s->st[s->top];elsereturn error;}int IsEmpty(op_stack *s) //定义判断栈空的函数{if(s->top<0)return 0;elsereturn s->st[s->top].op;}char push(op_stack *s,opt c) //定义入栈函数{s->top++;s->st[s->top]=c;return c.op;}opt pop(op_stack *s) //定义出栈函数{opt i;opt error=;if(s->top>=0){i=s->st[s->top];s->st[s->top].op='\0';s->top--;return i;}elsereturn error;}void clear(op_stack *s) //定义初始化栈{s->top=-1;}//-----------------------------define the value stack----------------------- double Dpeek(D_stack *s) //定义看栈顶函数{if(s->top>=0)return s->D[s->top];elsereturn 0;}int DIsEmpty(D_stack *s) //定义判断栈空的函数{if(s->top<0)return 0;elsereturn (int)(s->D[s->top]);}double Dpush(D_stack *s,double c) //定义入栈函数{s->top++;s->D[s->top]=c;return c;}double Dpop(D_stack *s) //定义出栈函数{double i;if(s->top>=0){i=s->D[s->top];s->D[s->top]='\0';s->top--;return i;}else return 0;}void Dclear(D_stack *s) //定义初始化栈{s->top=-1;}double calval(char *exp){op_stack os; //定义两个栈D_stack ds;char tmp[MAXLEN]=;int i=0,leng;double dtmp,dpoptmp;opt A=;opt R=;opt M=;opt D=;opt B=;opt Mo=;clear(&os);Dclear(&ds);//-----定义初始化结束-----while(*exp!='\0'){while(*exp >= '0' && *exp <= '9' || *exp == '.') {while(*exp >= '0' && *exp <= '9' || *exp == '.') {tmp[i++]=*exp++;}dtmp=atof(tmp);Dpush(&ds,dtmp);leng=strlen(tmp);for(i=0;i<leng;i++){tmp[i]='\0';}i=0;}//-------------------------------switch(*exp){case '+' :if(!IsEmpty(&os) || peek(&os).level < A.level){push(&os,A);*exp++;}else{while(IsEmpty(&os) && peek(&os).level>=A.level) {switch(pop(&os).op){case '%':dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp);Dpush(&ds,dpoptmp);break;case '*' :dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case '/' :dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case '+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);break;case '-':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,A);*exp++;}break;case '-':if(!IsEmpty(&os) || peek(&os).level < R.level){push(&os,R);*exp++;}else{while(IsEmpty(&os) && peek(&os).level>=R.level) {switch(pop(&os).op){case '%' :dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp);Dpush(&ds,dpoptmp);break;case '*' :dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case '/' :dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case '+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);break;case '-':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,R);*exp++;}break;case '*':if(!IsEmpty(&os) || peek(&os).level < M.level){push(&os,M);*exp++;}else{while(IsEmpty(&os) && peek(&os).level>=M.level) {switch(pop(&os).op){case '%' :dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp);Dpush(&ds,dpoptmp);break;case '*' :dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case '/' :dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,M);*exp++;}break;case '/':if(!IsEmpty(&os) || peek(&os).level < D.level){push(&os,D);*exp++;}else{while(IsEmpty(&os) && peek(&os).level>=D.level) {switch(pop(&os).op){case '%' :dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp);Dpush(&ds,dpoptmp);break;case '*' :dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case '/' :dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,D);*exp++;}break;case '%':if(!IsEmpty(&os) || peek(&os).level < Mo.level){push(&os,Mo);*exp++;}else{while(IsEmpty(&os) && peek(&os).level>=Mo.level) {switch(pop(&os).op){case '%' :dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp);Dpush(&ds,dpoptmp);break;case '*' :dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case '/' :dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;}}push(&os,Mo);*exp++;}break;case '(':push(&os,B);exp++;break;case ')':while(peek(&os).level!=-2){switch(pop(&os).op){case '%' :dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp);Dpush(&ds,dpoptmp);break;case '*' :dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case '/' :dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case '+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);break;case '-':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp;Dpush(&ds,dpoptmp);break;}}pop(&os); //弹出(exp++;break;}}while(IsEmpty(&os)){switch(pop(&os).op){case '%' :dpoptmp=Dpop(&ds);dpoptmp=(float)((int)Dpop(&ds)%(int)dpoptmp);Dpush(&ds,dpoptmp);break;case '*' :dpoptmp=Dpop(&ds)*Dpop(&ds);Dpush(&ds,dpoptmp);break;case '/' :dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)/dpoptmp;Dpush(&ds,dpoptmp);break;case '+':dpoptmp=Dpop(&ds)+Dpop(&ds);Dpush(&ds,dpoptmp);break;case '-':dpoptmp=Dpop(&ds);dpoptmp=Dpop(&ds)-dpoptmp;Dpush(&ds,dpoptmp);break;}}return Dpop(&ds);}void main(){char string[MAXLEN];char *p=string;printf("输入表达式:\n");gets(p);printf("%s=%f\n\n",string,calval(p));。

相关文档
最新文档