利用栈求表达式的值

合集下载

考研计算机学科专业基础综合-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个不同元素的有序序列的折半查找,采用一个递归工作栈时,该栈的最小容量应为( )。

基于栈的后缀算术表达式求值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++四则运算表达式求值算法
的字符串。
u 这里定义了两个构造函数,不带参数的默认 m_string 为空,带 string 类型
参数的将参数值赋予成员变量 m_string,此外还定义了赋值运算符“=”,
目 的是将一个表达式字符串 赋予 成员变量 m_string 。 因此 生 成一个 ExpressionType 的对象可以有如下两种形式: ExpressionType expr(“(2.99-4.32)*(90.8-78.66)+78.0/3.14”); 或者 ExpressionType expr; Expr = “(2.99-4.32)*(90.8-78.66)+78.0/3.14”; u DivideExpressionToItem(): 私有成员函数,返回值是一个 string 类型的 队列。其功能是将原始的中缀表达式中的操作数、操作符以及括号按顺序以 字符串的形式分解出来,然后保存在一个队列中(队列的操作规则是先进先 出)。 u ChangeToSuffix(): 私有成员函数,返回值是一个 string 类型的栈。其功 能是将队列中表示原始表达式各项的字符串调整顺序,转换成后缀表达式的 顺序,并处理掉括号,然后保存在一个栈中(栈的操作规则是先进后出)。 u IsWellForm():私有成员函数,返回 bool 值。其功能是判断原始表达式中的 括号是否匹配,如果匹配返回 true,否则返回 false。 u Size():返回原始表达式所包含的字节数。 u Calculate(): 公有成员函数,返回 double 类型的值。其功能是计算转换后 的后缀表达式的值,即原始中缀表达式的值。
abc然后分别按从左到右放入栈中如果碰到操作符就从栈中弹出两个操作数进行运算最后再将运算结果放入栈中依次进行直到表达式放入栈中然后碰到操作符则从栈中弹出的运算并将其结果d假设为放入栈中最后是操作符所以再弹出进行dc运算并将其结果再次放入栈中此时表达式结束则栈中的元素值就是该表达式最后的运算结果

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

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

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

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

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

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

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

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

实验三基于栈结构的中缀表达式求值班级:计科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 数据结构基础知识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.线性表的()存储结构是随机存储结构。

四则运算表达式求值(栈+二叉树-c++版)

四则运算表达式求值(栈+二叉树-c++版)

HUNAN UNIVERSITY 课程实习报告题目:四则运算表达式求值学生:周华毅学生学号:201308010411专业班级:计科1304 指导老师:吴帆完成日期:2015/5/1一、需求分析a)四则运算表达式求值,将四则运算表达式用中缀表达式表示,然后转换为后缀表达式,并计算结果。

b)本程序要求利用二叉树后序遍历来实现表达式的转换,同时可以使用实验2的结果来求解后缀表达式的值。

c)在字符界面上输入一个中缀表达式,回车表示结束。

如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。

d)测试数据输入:21+23*〔12-6〕输出:21 23 12 6 -*+二、概要设计抽象数据类型为实现上述程序的功能,应以字符串存储用户的输入,以及计算出的结果。

算法的基本思想根据题目要求,利用二叉树后序遍历来实现表达式的转换。

该算法的基本模块包括二叉树的建立以及如何把输入的中缀表达式利用二叉树后序遍历转化为后缀表达式。

1、首先要将输入的中缀表达式〔数字字符〕存入到二叉树中,由于存在两位或者两位以上的数,甚至还有小数,所以考虑用字符型指针存储数字字符和操作符。

2、为了便于将中缀表达式存入二叉树中,在录入中缀表达式后,要进行相应的处理,比方去掉空格符,添加结束标志,如‘=’、‘#’等。

3、中缀表达式存入到二叉树的过程中,要注意处理的顺序,如‘+’、‘-’号的优先级比‘*’、‘/’号的低,当遇到‘*’、‘/’号时,要判断树以上的节点中是否有‘+’、‘-’号,有的话要与其交换位置。

遇到‘〔’时要反复创建二叉树的结点,构建子二叉树,考虑到括号内要处理的步骤可能会较多,可以考虑用递归。

遇到‘〕’时则直接结束此子二叉树的建立。

此外二叉树中叶子结点存储操作数,非叶子结点存储操作码。

4、对创建好的二叉树进行后序遍历,即可得到相应的后缀表达式,实现方法可以用递归的方式,由于后面还要计算表达式的值,故便利的过程中要将结点中得到的数据存入新的字符数组中。

表达式求值(无括号)

表达式求值(无括号)

表达式求值(⽆括号)对于⾃然数的表达式求值,操作有加、减、乘、除和幂运算,分别⽤+,-, *, /,^来表⽰,为⽅便运算,加⼊#运算符,其运算优先级最低,由于运算符优先级不⼀样,可以利⽤栈实现此操作。

算法思想(1)规定运算符的优先级表(2)设置两个栈:OVS(运算数栈)和OPTR(运算符栈),为了操作⽅便可以先在OPTR栈中先放⼀个#运算符(3)⾃左向右扫描,进⾏如下处理:若遇到运算数则⾦OVS栈;若遇到运算符则与OPTR栈顶运算符进⾏⽐较:•如果当前运算符的优先级⼤于OPTR栈顶运算符的优先级,则当前运算符进⼊OPTR栈;•如果当前运算符的优先级⼤于等于OPTR栈顶运算符的优先级,则OPTR退栈⼀次,得到栈顶运算符op,连续退栈OVS两次,得到运算数a 和b,执⾏op运算,得到结果T,将T进OVS栈。

可以⾃⼰画⼀个表达式两个栈的变化图,有助于理解#include<stdio.h>#include<stdlib.h>#include<math.h>#include<stdbool.h>typedef struct node{int data;//⽆论对于运算符还是运算数,都⽤int型变量来保存node *next;}LinkStackNode, *LinkStack;void InitStack(LinkStack *S){//初始化链栈*S = (LinkStack)malloc(sizeof(LinkStackNode));(*S)->next = NULL;}int Push(LinkStack top, int x){// 进栈操作LinkStackNode *temp;temp = (LinkStackNode*)malloc(sizeof(LinkStackNode));if(temp == NULL) return0;temp->data = x;temp->next = top->next;top->next = temp;return1;}int Pop(LinkStack top, int *x){//出栈操作LinkStackNode *temp;temp = top->next;if(temp == NULL) return0;*x = temp->data;top->next = temp->next;free(temp);return1;}int GetNum(char ch){//返回字符对应的数字return ch - '0';}bool IsEmpty(LinkStack top){//栈为空返回假if(top->next == NULL) return false;return true;}int GetTop(LinkStack top){//返回栈顶元素if(top->next == NULL) return1;return top->next->data;}char Compare(char ch1, char ch2){//实现运算符优先级⽐较switch(ch1){case'#':switch(ch2){case'#': return'=';case'+':case'-':case'*':case'/':case'^': return'<';}case'+':switch(ch2){case'#': return'>';case'+':case'-': return'=';case'*':case'/':case'^': return'<';}case'-':switch(ch2){case'#': return'>';case'+':case'-': return'=';case'*':case'/':case'^': return'<';}case'*':switch(ch2){case'#':case'+':case'-': return'>';case'*':case'/': return'=';case'^': return'<';}case'/':switch(ch2){case'#':case'+':case'-': return'>';case'*':case'/': return'=';case'^': return'<';}case'^':switch(ch2){case'#':case'+':case'-':case'*':case'/': return'>';case'^': return'=';}}}int Calculate(int a, char op, int b){//计算 a op b 的值int c;switch(op){case'-': c = a - b; break;case'+': c = a + b; break;case'*': c = a * b; break;case'/': c = a / b; break;case'^': c = pow(a, b); break;default : c = 0;}return c;}int ExpEvaluation(){//实现LinkStack ovs, optr;InitStack(&ovs);InitStack(&optr);Push(optr, (int)'#');printf("\n\nPlease input an expression(Ending with '#'):\n");char ch = getchar();int num = 0, a, b, t, op, zan;while(ch != '#' || (char)GetTop(optr) != '#'){while(ch >= '0' && ch <= '9'){//如果数字不是⼀位数字,便把字符转化为数字 num = num * 10 + GetNum(ch);ch = getchar();}if(num != 0){//如果num不为0便进OVS栈Push(ovs, num);num = 0;//把num置零}else{switch(Compare(ch, (char)GetTop(optr))){//对运算符优先级进⾏⽐较,实现对应三种关系的操作case'>': Push(optr, (int)ch); ch = getchar(); break;case'=':case'<': Pop(optr, &op);Pop(ovs, &a);Pop(ovs, &b);t = Calculate(b, (char)op, a);Push(ovs, t);break;}}}t = GetTop(ovs);//取栈顶元素,返回值return t;}int main(){int ans = ExpEvaluation();printf("%d\n", ans);return0;}。

利用栈进行表达式求值

利用栈进行表达式求值
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;

数据结构期末考试试题

数据结构期末考试试题

《数据结构》试题答案(闭卷)(电信系本科2008级2010年1月)姓名班级一、简答题 (每题4分,共40分)1.已知一个线性表有n(n<=30)个元素,其中每个元素的数据占8个字节。

假设一个指针的大小为4个字节。

如果采用有30个元素的定长数组存储,那么当数组中有效元素个数n 满足什么条件时,数组的存储效率比不带头结点的单链表更高?答:8*30<(8+4)*nn>202.给定12个字母,假设他们的权值都相等。

采用Huffman编码,则每个字母的平均编码长度是多少?答:按Huffman树建立规则,应有4个3Bit码和8个4Bit码,则平均码长为(4*3+8*4)/12=3.673.利用栈计算表达式((A-B)-C)-(D+(E-F)) 的值,操作数栈和运算符栈的深度最小各是多少?答:5项4项4. 在一棵有n个结点的树中,只存在度为m和度为0的结点,给出叶子结点的数目。

设: n=n m+n0 , 关系个数n-1=m* n m解此方程组n0=n-(n-1)/m5.找出满足在中序遍历和后序遍历时,所得到的结点访问序列相同的二叉树。

答:该二叉树为只有一个结点的二叉树或右单支树6.欲将无序序列(23, 78, 12, 35, 69, 95, 11, 09, 35*, 48, 99, 26)中的关键字由大到小重新排列,请写出快速排序第一趟排序的结果序列。

原始序列7.设模式串为“大学生中华华中科技大学大学生活”,求该模式串的next函数,next函数值与模式串向右滑动距离的关系是什么?next =0 1 1 1 1 1 1 1 1 1 2 3 2 3 48.设有1000 个结点(有序),用二分法查找时,最大比较次数是多少?答:1000个有序节点采用二分查找时的查找判定树深度为10,故最大比较次数为109.设有150个记录要存储到散列表中,并利用线性探查法解决冲突,要求找到所需记录的平均比较次数ASL不超过2次。

栈的应用实验报告

栈的应用实验报告

栈的应用实验报告栈的应用实验报告引言:栈是一种常见的数据结构,它具有后进先出(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。

栈的应用实验报告

栈的应用实验报告

数据结构实验报告报告名称栈的应用专业网络工程班级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)若是其它字符,则返回错误信息。

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(int cur_opnd):简单计算+,-,*,/ double pop_num():弹出操作数源代码:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define MAXSIZE 100#define N 1000int i=0; //表达式数typedef struct expression//表达式结构{long double result;char expstr[MAXSIZE];}expression;expression expr[N];//表达式的一个整体容器s typedef struct//操作码栈定义{char code[MAXSIZE];int top;}opnd;typedef struct//操作数栈定义{double date[MAXSIZE];int top;}num;//《——opnd栈操作——》:void initstack(opnd *op)//初始化栈{op->top=-1;}int empty_opnd(opnd *op)//判空{if(op->top==-1)return 0;else return 1;}int push_opnd(opnd *op,char co)//压栈 {if(op->top==MAXSIZE-1){printf("The \"opnd\" stack is full.");return 0;}op->top++;op->code[op->top]=co;return 1;}char pop_opnd(opnd *op)//出栈{char a='\0';if(op->top==-1){printf("error:The \"opnd\" stack is empty."); return a;}a=op->code[op->top];op->top--;return a;}char get_opnd(opnd *op)//查看栈顶{char a='\0';if(op->top==-1){printf("error:The \"opnd\" stack is empty."); return a;}elsereturn op->code[op->top];}//《——num栈操作——》:void initstack(num *nu){nu->top=-1;}int empty_num(num *nu)//判空{if(nu->top==-1)return 0;else return 1;}int push_num(num *nu,double da)//压栈{if(nu->top==MAXSIZE-1){printf("error:The \"date\" stack is full."); return 0;}nu->top++;nu->date[nu->top]=da;return 1;}double pop_num(num *nu)//出栈{double a='\0';if(nu->top==-1){printf("error:The \"date\" stack is empty."); return a;}a=nu->date[nu->top];nu->top--;return a;}double get_num(num *nu)//查看栈顶{if(nu->top!=-1)return nu->date[nu->top];}//《——结束栈定义操作——》//《——函数操作——》:int change_opnd(char code)//将字符型操作码转换成优先级,非表达式字符反回-2{switch(code){case '=':return 1;break;case ')':return 2;break;case '+':return 3;break;case '-':return 3;break;case '*':return 4;break;case '/':return 4;break;case '(':return 0;break;//操作码级别>=0;case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':case '0':case '.': return -1;//操作数级别=-1;default: return -2;//其它符号级别=-2}}char procede(char top,char code)//处理操作码,判断栈的操作{if(change_opnd(code)==0)//“(”入栈return ('<');elseif(change_opnd(code)==2&&change_opnd(top)==0)//“(”和“)”同时出现,“(”出栈,“)”不入栈return ('=');elseif(change_opnd(code)<=change_opnd(top))//弹出两个数字和一个符号进行计算return ('>');elsereturn ('<');//入栈}double change_num(char str[])//数字字符串转成double型数字{char *s=str;int p=1,q=0;//p=小数点前位数,q=小数点后位数char d[]=".",z[]="0";double da=0,p1;if(strstr(str,d)==0)//判断是否有小数点p=strlen(str);elseif(strstr(str,d)==str)//没有输入小数点前的数,如“.032”{p=1;q=strlen(str)-1;strcpy(str,strcat(z,str));}else{p=strstr(str,d)-str;q=strlen(str)-p-1;}for(int i=0;i<p;i++) //小数点前的各位数乘以各自的阶数,然后叠加:123=1*100+2*10+3*1da=da+((int)str[i]-48)*pow(10,p-i-1);for(int j=0;j<q;j++) //小数点后的各位数乘以各自的阶数,然后叠加:0.123=1*0.1+2*0.01+3*0.001da=da+((int)str[strlen(str)-1-j]-48)*pow(0.1,q-j);return da;}int make_str()//语法检查{char *p,*p1;int n=0;printf("\n请输入表达式,以“=”结尾:");gets(expr[i].expstr);p=expr[i].expstr;p1=p;while(1){if(*p=='\0')if(*(p-1)=='=')//语法检查结束break;else{//没有以"="结尾printf("\n表达式以\"=\"结尾。

请重新输入:"); gets(expr[i].expstr);p=expr[i].expstr;n=0;continue;}if(change_opnd(*p)==2)//一个")",n-1n--;if(change_opnd(*p)==0)//一个"(",n+1n++;if(*p1==*p)//第一个字符的判断,只能以“数字”或“(”开头,不能有非法字符if(change_opnd(*p)>0){printf("\n表达式只能以“数字”或“(”开头。

请重新输入:");gets(expr[i].expstr);p=expr[i].expstr;n=0;continue;}elseif(change_opnd(*p)==-2){printf("\n表达式\"%c\"为非法字符。

请重新输入:",*p);gets(expr[i].expstr);p=expr[i].expstr;n=0;continue;}else{//合法刚跳到下一个字符p=p+1;continue;}if(change_opnd(*p)==-2)//非法字符判断{printf("\n表达式\"%c\"为非法字符。

相关文档
最新文档