实验三  算术表达式求值(必做,设计性实验)

  1. 实验目的

熟练掌握栈的基本操作,深入了解栈的特性,能在实际问题的背景下灵活运用他们,并加深对这种结构的理解。

  1. 实验内容

设计一个程序,演示用算符优先法对算术表达式求值的过程。以字符序列的形式从终端输入语法正确的、不含变量的整数表达式。利用教科书表3.1给出的算符优先关系,实现对算术四则运算混合运算表达式的求值,并仿照教科书的例子3-1演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化。测试数据可以选择例子3-1的算术表达式 3*(7-2),或自选。

  1. 数据结构定义

(说明你算法中用到的数据结构、数据类型的定义)

栈是一种只能在一端进行插入或删除操作的线性表。表中允许插入、删除操作的一端称为栈顶。栈顶的当前位置是动态的,栈顶的当前位置由一个称为栈顶指针的位置指示器指示。当栈中没有元素时,为空栈,栈的插入操作和删除操作通常称为进栈和出栈。栈的主要特点是后进先出。

Typedef struct{SElemType *base;SElemType *top;Int stacksize;}SqStack;

stacksize表示栈当前可使用的最大容量。Base时栈底指针,top作为栈顶指针。

  1. 算法思想及算法设计

(先文字说明算法的思想,然后给出类C语言算法)

为实现算符优先算法,我们使用两个工作栈,,一个称作OPTR,用以寄存运算符;另一个称作OPND,用以寄存操作数或者运算结果,依次读入每个字符,若操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后在操作,直到整个表达式求值完毕。

void GetExpressionValue(){SqStack OPTR,OPND;SElemType result;//返回最后结果InitStack(&OPTR);InitStack(&OPND);Push(&OPTR,'#');//将结束符置于操作符的底端  printf("请输入算术表达式:\n");char c = getchar();while(c!='#'||GetTop(&OPTR)!='#'){//当*c=='#'&&栈顶字符=='#'的时候if(isdigit(c)){//如果是数字的话将其转化为数字 然后入操作数栈int data[10];int i,num; i = num =0;//num是一个中间数 用于将字符串中的数字转化为整数然后入栈 i用于将字符串中的字符存入data数组while(isdigit(c)){data[i] = c-'0'; i++; c = getchar();}for(int j=0;j<i;j++){num = num*10+data[j];}Push(&OPND,num);}else{//如果是字符的话将其入操作符栈SElemType a,b,theta;//a b theta是用来返回操作数栈和操作符栈里的元素的switch(Priority(GetTop(&OPTR),c)){//比较即将入栈的字符与栈顶 操作符的优先级关系case '<':Push(&OPTR,c);c = getchar();break;case '>':Pop(&OPND,&b);Pop(&OPND,&a);Pop(&OPTR,&theta);Push(&OPND,Reckon(a,theta,b));break;//将结果入栈case '=':Pop(&OPTR,&theta);c = getchar();break;//说明括号相遇 删除栈内括号即可default:break;} }}Pop(&OPND,&result);printf("结果是:%d",result);}
  1. 实验代码

(即C语言程序)

#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define STACKINCREMENT 5#define STACK_INIT_SIZE 10typedef char SElemType;typedef int Status;typedef struct{SElemType *base;//栈底指针SElemType *top;//栈顶指针int stacksize;//当前已经分配的存储空间}SqStack;char prior[7][7]={{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'},{'>','>','>','>','<','>','>'},{'<','<','<','<','<','=','!'},{'>','>','>','>','!','>','>'},{'<','<','<','<','<','!','='}};//定义算符之间优先关系的二维数组//构造一个存放char型数据的空栈Status InitStack(SqStack *s){s->base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!s->base) return ERROR;s->top = s->base;//栈中元素个数为0s->stacksize = STACK_INIT_SIZE;return OK;}//入栈Status Push(SqStack *s,SElemType e){if(s->top-s->base>=s->stacksize){s->base = (SElemType *)realloc(s->base,(STACKINCREMENT+s->stacksize)*sizeof(SElemType));if(!s->base) exit(0);s->top = s->base+s->stacksize;s->stacksize += STACKINCREMENT;}*s->top++ = e;return OK;}//出栈Status Pop(SqStack *s,SElemType *e){if(s->base==s->top){printf("空栈!\n");return ERROR;}*e = *--s->top;return OK;}//得到栈顶元素SElemType GetTop(SqStack *s){return *(s->top-1);}//确定输入的字符如果是操作符的话判断在二维数组中的下标 若是数字的话就另外与操作符区分开 便于在输入表达式时是入哪个栈int Index(char c){switch(c){case '+': return 0;case '-': return 1;case '*': return 2;case '/': return 3;case '(': return 4;case ')': return 5;case '#': return 6;default:  return 7;}}//判断优先级,返回大小 < > = !char Priority(char a,char b){int x,y;x = Index(a); y = Index(b);if(x!=7&&y!=7)return prior[x][y];elsereturn '!';}//简单表达式求值int Reckon(int a,char theta,int b){switch(theta){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;}}//判断是字符是否是数字Status isdigit(char ch){if(ch>='0'&&ch<='9') return OK;return ERROR;}//算术表达式求值void GetExpressionValue(){SqStack OPTR,OPND;SElemType result;//返回最后结果InitStack(&OPTR);InitStack(&OPND);Push(&OPTR,'#');//将结束符置于操作符的底端  printf("请输入算术表达式:\n");char c = getchar();while(c!='#'||GetTop(&OPTR)!='#'){//当*c=='#'&&栈顶字符=='#'的时候if(isdigit(c)){//如果是数字的话将其转化为数字 然后入操作数栈int data[10];int i,num;i = num =0;//num是一个中间数 用于将字符串中的数字转化为整数然后入栈 i是用于将字符串中的字符存入data数组while(isdigit(c)){data[i] = c-'0';i++;c = getchar();}for(int j=0;j<i;j++){num = num*10+data[j];}Push(&OPND,num);}else{//如果是字符的话将其入操作符栈SElemType a,b,theta;//a b theta是用来返回操作数栈和操作符栈里的元素的switch(Priority(GetTop(&OPTR),c)){//比较即将入栈的字符与栈顶 操作符的优先级关系case '<':Push(&OPTR,c);c = getchar();break;case '>':Pop(&OPND,&b);Pop(&OPND,&a);Pop(&OPTR,&theta);Push(&OPND,Reckon(a,theta,b));break;//将结果入栈case '=':Pop(&OPTR,&theta);c = getchar();break;//说明括号相遇 删除栈内括号即可default:break;}}}Pop(&OPND,&result);printf("结果是:%d",result);}
  1. 算法测试结果

(说明测试数据,粘贴实验结果图)

实验数据:3*(5+2)  9/(5+2)

  1. 分析与总结

(1)算法复杂度分析及优、缺点分析

(说明你编写算法的复杂度,算法的优点和缺点有哪些)

数据压缩存储栈,其操作主要有: 

建立栈int Push(SeqStack *S, char x) 入栈int Pop(SeqStack *S, char x) 出栈。 

以上各操作运算的平均时间复杂度为O(n),其主要时间是耗费在输入操作。

(2)实验总结

(说明你怎么解决实验中遇到的问题,有什么收获)

通过这次实验,让我复习了栈的知识,增强的我的c语言编程能力。

做什么都需要耐心,做设计写程序更需要耐心。一开始的时候,我写函数写的很快,可是等最后调试的时候发现错误很隐蔽,就很费时间了。后来我先在纸上构思出函数的功能和参数,考虑好接口之后才动手编,这样就比较容易成功了。

数据结构 实验三 算术表达式求值 栈的基本操作相关推荐

  1. 数据结构 C++实现 算术表达式求值

    文章目录 一.实验目的 二.实验要求 三.代码内容 1.创建链栈并初始化 2.入栈出栈取栈顶元素 3.判断是否是运算符 4.判断运算符优先级 5.运算函数 6.总代码 四.运算结果 五.总结 一.实验 ...

  2. 算术表达式求值演示(C/C++实现)

    算术表达式求值演示 问题描述:表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的典型例子.设计一个程序,演示用算符优先法对算术表达式求值的过程. 基本要求:以字符序列的形式从键盘输入语法正确的 ...

  3. 【数据结构】栈的应用-算术表达式求值#数据结构实验任务书

    实验题目:栈的应用-算术表达式求值 正文 实验环境: Visual C++ 2010 实验目的: 1.掌握栈的定义及实现: 2.掌握利用栈求解算术表达式的方法. 实验内容: 通过修改完善教材中的算法3 ...

  4. 北京林业大学数据结构实验二 基于栈的算术表达式求值算法

    第1关:基于栈的中缀算术表达式求值 参见课本P75 例3.3 #include <iostream> #include<iomanip>#define MAXSIZE 100 ...

  5. 编程题实训-实验2-基于栈的算术表达式求值算法(北京林业大学)

    第1关:基于栈的中缀算术表达式求值 任务描述 本关任务:输入一个中缀算术表达式,求解表达式的值.运算符包括+.-.*./.(.).=,参加运算的数为double类型且为正数.(要求:直接针对中缀算术表 ...

  6. 数据结构—— 基于二叉树的算术表达式求值

    实验五 基于二叉树的算术表达式求值 数据结构--中序表达式求值(栈实现) 实验目的: 1.掌握二叉树的二叉链表存储表示和二叉树的遍历等基本算法. 2.掌握根据中缀表达式创建表达式树的算法 3.掌握基于 ...

  7. 算术表达式求值的程序设计与实现_数据结构课程设计

    以下内容可且仅可供参考,如有错误欢迎指正. 部分思路借鉴算术表达式求值(C语言栈)_夜何其的博客-CSDN博客_c语言利用栈求解算术表达式侵删致歉 <算术表达式求值的程序设计与实现>题目要 ...

  8. 《Algorithms》—— Dijkstra 的双栈算术表达式求值算法

    想当年学数据结构的时候,一直觉得这个是我一辈子都搞不懂的一个东西.现在看看...还挺简单的... 重点在于如何解析由括号.运算符和数字组成的字符串,并按照正确的顺序完成各种初级算术操作.利用了两个栈( ...

  9. 算术表达式求值(C语言栈)

    题目:算术表达式求值 题目描述:表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子.设计一个程序,演示用运算符优先法对算数表达式求值的过程. 基本要求:以字符序列的形式从终端输入语 ...

  10. 【Java】基于栈的算术表达式求值

    定义异常类 public class ExpressionException extends RuntimeException {private static final long serialVer ...

最新文章

  1. UE capability与 双连接相关的参数。
  2. 【Codeforces】501B Misha and Changing Handles(map)
  3. 如何维持手机电池寿命_一块能用百年的手机电池将诞生,你愿意花高价购买吗?...
  4. 殊途同归的fork()
  5. 微擎css使用php变量,$_Wamp;全局变量
  6. LInux 阿里云系统遇到挖矿程序
  7. 这枚纸币为什么这么贵?
  8. Java爬虫工程师技能列表
  9. 基本数据类型与引用数据类型
  10. GNS3安装和使用教程
  11. 网卡基本配置2(主机名修改、网卡绑定)
  12. 重庆市总工会送法到中建三局城建档案馆项目
  13. vue项目中,使用require动态加载本地图片报错找不到模块
  14. 安卓模拟器按键_超好用的网易MuMu安卓模拟器(兼容MacOS10.15系统)
  15. 阿里云PCDN新亮点 自动调用HTTPDNS 解决域名劫持困扰
  16. 企业级应用撕逼大战 toB产业链竞争升级
  17. SQLserver 连接服务器样例
  18. centos7.9下lsblk以及df -Th卡顿问题涉及iscsi
  19. 在虚拟机中通过U盘GHOST 操作系统
  20. 如何隐藏控制台窗口?

热门文章

  1. 涨姿势 之 Sourcetree 显示头像
  2. 邮件服务器SASL TLS 反垃圾邮件系统
  3. 睁开双眼玩立体游戏!3D显示技术解析
  4. android10怎么截屏,安卓手机怎么截图?安卓手机截图方法大全
  5. QT 信号toggled triggered区别
  6. 品今第一届集团迎新分享会,进•无止境
  7. centos网卡配置
  8. 计算机硬件与哪些部分组成部分,计算机硬件组成及各部分功能有哪些?
  9. php 上传微信客服头像,微信多客服上传头像
  10. 双系统linux grub rescue,WindowsUbuntu双系统一键Ghost,提示grub rescue的解决方法