数据结构实验:计算表达式的值--顺序栈
Posted 希声lx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构实验:计算表达式的值--顺序栈相关的知识,希望对你有一定的参考价值。
实验题目:栈的应用-算术表达式求值
实验环境: Visual C++ 6.0
实验目的 :
1 .掌握栈的定义及实现;
2 .掌握利用栈求解算术表达式的方法。
实验内容:
通过修改完善教材中的算法3.4,利用栈来实现算术表达式求值的算法。对算法3.4中调用的几个函数要给出其实现过程:
(1) 函数In(c):判断c是否为运算符;
(2) 函数Precede(t1,t2):判断运算符t1和t2的优先级;
(3) 函数Operate(a,theta,b):对a和b进行二元运算theta。
程序运行时,输入合法的算术表达式(中间值及最终结果要在0~9之间,可以包括加减乘除和括号),便可输出相应的计算结果。如下图:
实验提示 : (仅供参考,每个函数的具体实现可以有多种方法,希望有创新)
1. 将栈的定义和实现单独保存在头文件“stack.h”中,然后在表达式求值的源程序中包含此头文件(即#include“stack.h”)。
2. 表达式求值源程序的具体实现
(1) 主函数如下:
void main()
{
Printf(“ 请输入算术表达式,并以#结束.\n”);
Printf(“the result of expression is:%d\n”,EvaluateExpression());
}
(2) 函数EvaluateExpression的实现见算法3.22
(3) 函数In(c)的实现可以采用以下方式:
Status In(SElemType c)// 应在前面有定义typedef char SElemType;
{ // 判断c是否为运算符
switch(c)
{
case‘+‘:return TRUE;
……// 补充完整
default:return FALSE;
}
}
(4) 函数Precede(t1,t2)的实现可以采用以下形式:
SElemType Precede(SElemType t1,SElemType t2)
{ // 根据教材表3.1,判断两个运算符的优先关系
SElemType f;
switch(t2)
{
case ‘+‘:
case ‘-‘:if(t1==‘(‘||t1==‘#‘)
f=‘<‘;
else
f=‘>‘;
break;
……// 补充完整
}
return f;
}
(5) 函数Operate(a,theta,b)的实现可以采用以下方式:
SElemType Operate(SElemType a,SElemType theta,SElemType b)
{
SElemType c;
a=a-48;
b=b-48;
switch(theta)
{
case‘+‘:c=a+b+48;
break;
……// 补充完整
}
return c;
}
选做内容: 进一步改进,使表达式的中间值及最终结果不局限于0~9之间的个位数。(如果完成要在实验报告中注明),如下图:
实验要求 :
(1) 程序要添加适当的注释,程序的书写要采用 缩进格式 。
(2) 程序要具在一定的 健壮性,即当输入数据非法时, 程序也能适当地做出反应。
(3) 程序要做到 界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
(4) 根据实验报告模板详细书写实验报告,在实验报告中给出 表达式求值算法的流程图 。
(5) 上传源程序到Sakai网络教学平台。顺序表的源程序保存为 calculator.cpp。
#include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<string.h> #define OVERFLOW -2 #define MAXSIZE 100 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #include<iostream> using namespace std; typedef int Status; typedef char SElemType; //--------顺序栈的存储结构------ typedef struct { SElemType *base; //栈底指针 SElemType *top; //栈顶指针 int stacksize; //占可用的最大容量 }SqStack; Status InitStack (SqStack &S) {//构造一个空栈 S.base=new SElemType[MAXSIZE]; //为顺序栈动态分配一个最大容量为MAXSIZE的数组空间 if (!S.base) exit(OVERFLOW); //动态分配失败 S.top=S.base; //top初始为base,空栈 S.stacksize=MAXSIZE; //stacksize置为栈的最大容量MAXSIZE return OK; } Status Push(SqStack &S,SElemType e) {//插入元素e为新的栈顶元素 if(S.top-S.base==S.stacksize) return ERROR; //栈满 *S.top++=e; //元素e压入栈顶,栈顶指针加1 return OK; } Status Pop(SqStack &S,SElemType &e) {//删除s的栈顶元素,用e返回其 if (S.top==S.base) return ERROR; //栈顶 e=*--S.top; // 栈顶指针减1,将栈顶元素为e return OK; } SElemType GetTop(SqStack S) {//返回S的栈顶元素,不修改栈顶指针、 if(S.top!=S.base) //栈非空 return *(S.top-1); //返回栈顶元素的值,栈顶指针不变 } Status In(SElemType c) { switch(c) //判断读入的字符是哪一种运算符, { case ‘+‘: return TRUE; break; case ‘-‘: return TRUE; break; case ‘*‘: return TRUE; break; case ‘/‘: return TRUE; break; case ‘(‘: return TRUE; break; case ‘)‘: return TRUE; break; case ‘#‘: return TRUE; break; default: return FALSE; } } SElemType Precede(SElemType t1,SElemType t2) { SElemType f; switch(t2) //判断运算符栈的栈顶元素和读入的运算符之间谁的优先级更高,并返回结果 { case ‘+‘: if (t1==‘(‘||t1==‘#‘) f=‘<‘; else f=‘>‘; break; case ‘-‘: if (t1==‘(‘||t1==‘#‘) f=‘<‘; else f=‘>‘; break; case ‘*‘: if (t1==‘+‘||t1==‘-‘||t1==‘(‘||t1==‘#‘) f=‘<‘; else f=‘>‘; break; case ‘/‘: if (t1==‘+‘||t1==‘-‘||t1==‘(‘||t1==‘#‘) f=‘<‘; else f=‘>‘; break; case ‘(‘: if (t1==‘+‘||t1==‘-‘||t1==‘(‘||t1==‘#‘||t1==‘*‘||t1==‘/‘) f=‘<‘; break; case ‘)‘: if (t1==‘+‘||t1==‘-‘||t1==‘*‘||t1==‘/‘||t1==‘)‘) f=‘>‘; else if (t1==‘(‘) f=‘=‘; break; case ‘#‘: if (t1==‘#‘) f=‘=‘; else f=‘>‘; break; default: cout<<"输入超出范围。。。"; } return f; } SElemType Operate(SElemType a,SElemType theta,SElemType b) { SElemType c; a=a-‘0‘; //因为a,b均为字符型,所以转化成int型 b=b-‘0‘; switch(theta) { case ‘+‘: c=a+b+‘0‘;break; //再将计算的结果转化为字符型 case ‘-‘: c=a-b+‘0‘;break; case ‘*‘: c=a*b+‘0‘;break; case ‘/‘: c=a/b+‘0‘;break; } return c; //返回计算结果 } char EvaluateExpression() {//算数表达式求值的算符优先算法,设OPTR和 OPND分别为运算符栈和操作数栈 SqStack OPND,OPTR; char ch,theta,a,b,c,x,w; InitStack(OPND); //初始化OPND栈 InitStack(OPTR); //初始化OPTR栈 Push(OPTR,‘#‘); //将表达式起始符“#”OPTR栈 cin>>ch; while (ch!=‘#‘||GetTop(OPTR)!=‘#‘) //表达式没有扫描完毕或者OPTR的栈顶元素不为“#” { if (!In(ch)) //判断ch是不是运算符,不是则压入OPND栈 { Push(OPND,ch); cin>>ch; } else switch(Precede(GetTop(OPTR),ch)) // 比较OPTR的栈顶元素和ch的优先级 { case ‘<‘: Push(OPTR,ch); //当前字符ch压入OPTR栈 ,读入下一个字符ch cin>>ch; break; case ‘>‘: Pop(OPTR,theta); //弹出OPTR栈顶的运算符 Pop(OPND,b); //弹出OPND栈顶的运算数, Pop(OPND,a); //弹出OPND栈顶的运算数, Push(OPND,Operate(a,theta,b)); //将运算结果压入OPND栈 break; case ‘=‘: //OPTR的栈顶元素是“(”且ch是“)” Pop(OPTR,x); //弹出OPTR栈顶的"(", cin>>ch; //读入下一个字符ch break; } } return GetTop(OPND); //OPND栈顶元素即为表达式求值结果 } int main() { char w; cout<<"请输入算数表达式,并以#结束\n"; w=EvaluateExpression(); //将运算结果赋值给w w=w-48; //将字符转换成数字 printf("The result of expression is %d\n",w); }
以上是关于数据结构实验:计算表达式的值--顺序栈的主要内容,如果未能解决你的问题,请参考以下文章