题目:设计一个程序,演示用算符优先法对算数表达式求值的过程。

一、需求分析

以字符序列的形式从终端读入输入语法正确、不含变量的整数表达式。利用教科书表3.1给出的算符优先关系,实现对算数四则混合运算表达式的求值,并仿照教科书的例子3-1演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。

2.测试数据

(1)3*(7-2);

(2)8;1+2+3+4;88-1*5;1024/4*8;1024/(4*8);(20+2)/(6/2);

(3)3-3-3;8/(9-9);2*(6+2*(3+6*(6+6)));(((6+6)*(6+3)*2+6)*2;

二、概要设计

1. 数据结构

主要数据类型为:

ADT Stack{

数据对象:

D={ai|a∈EleSet,i=1,2,...,n,n≥0}

数据关系:R1={|ai-1,ai∈D,i=2,...,n}

约定an为栈顶,a1为栈底。

基本操作:

InitStack(&S)

操作结果:构造一个空栈S

GetTop(S, &e)

初始条件:栈S已存在且非空

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

Pop(&S, &e)

初始条件:栈S已存在

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

Push(&S, e)

初始条件:栈S已存在

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

}

2. 使用函数

int InitTRStack(TRStack *S)

int InitNDStack(NDStack *S)

操作结果:构造运算符栈和操作数栈

char TRGetTop(TRStack *S)

float NDGetTop(NDStack *S)

操作结果:返回运算符栈和操作数栈的栈顶元素

int TRPush(TRStack *S, char e)

int NDPush(NDStack *S, float e)

操作结果:插入栈顶元素

int TRPop(TRStack *S, char *e)

int NDPop(NDStack *S, float *e)

操作结果:删除栈顶元素,返回其值

float Opreate(float a, float b, char theta)

操作结果:对操作数和对应的运算符进行计算返回结果

int In(char c,char *OP)

操作结果:判定字符是否为运算符

char Precede(char m, char n, char *OP)

操作结果:判断运算符的优先级

int OutPutNDStack(NDStack *S)

int OutPutTRStack(TRStack *S)

操作结果:输出运算符和操作数栈内所有元素

三、详细设计

1. 数据储存结构

运算符栈采用char类型栈,操作数栈采用float类型栈

OPND和OPTR栈的实现如下:

typedef struct {

char *base;

char *top;

int stacksize;

}TRStack;

typedef struct {

float *base;

float *top;

int stacksize;

}NDStack;

2. 计算功能实现

为实现算符优先级算法,使用两个工作栈,一个称作OPTR,用以寄存运算符,一个称作OPND,用以寄存操作烁或运算结果。算法的基本思想为:

(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;

(2)依次读入表达式中的每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较有限权后做相应操作,直到OPTR栈的栈顶元素和当前读入字符均为“#”

float EvaluateExpression(char *expr){

// 算数表达式求值的算符优先算法。OPTR和OPND分别为运算符栈和运算数栈

// OP为运算数的集合

char OP[8] = {'+','-','*','/','(',')','#','\0'};

TRStack OPTR; NDStack OPND;

char *c;

char End[] = {'#','\0'};

char cc[254];

float a,b;

char theta,x;

float cf;

InitTRStack(&OPTR); TRPush(&OPTR,'#');

InitNDStack(&OPND); c = strcat(expr,End); // 拼接表达式使其以#结尾

while(*c!='#' || TRGetTop(&OPTR)!='#') {

if(!In(*c,OP)){

while(!In(*c,OP)){strcat(cc,c);c++;} // 两位数以上数字输入

cf = atof(cc);

OutPutTRStack(&OPTR);

OutPutNDStack(&OPND);

printf("输入字符:%f ",cf);

memset(cc, 0x00, sizeof (char) * 256); // 清空临时字符串

NDPush(&OPND,cf);

printf("操作:Push(OPND,%f)\n",cf);

} // 不是运算符进栈

else{

OutPutTRStack(&OPTR);

OutPutNDStack(&OPND);

printf("输入字符:%c ",*c);

switch(Precede(TRGetTop(&OPTR),*c,OP)){

case'

TRPush(&OPTR,*c);

printf("操作:Push(OPTR,%c)\n",*c);

c++;

break;

case'=': // 脱括号指针移动到下一字符

TRPop(&OPTR,&x);

printf("操作:Pop(OPTR,%c)\n",x);

c++;

break;

case'>': // 退栈并将运算结果入栈

TRPop(&OPTR,&theta);

NDPop(&OPND,&b);

NDPop(&OPND,&a);

NDPush(&OPND,Opreate(a,b,theta));

printf("操作:Opreate(%f,%c,%f)\n",a,theta,b);

break;

}

}

}

OutPutTRStack(&OPTR);

OutPutNDStack(&OPND);

printf("输入字符:%c ",*c);

printf("操作:return GetTop(OPND)\n");

return NDGetTop(&OPND);

}

4. 主程序

通过判断读入表达式中元素是否仅为数字和符号以及左右括号数目是否相等来决定是否进行下一步计算

int main(){

// cnt1,cnt2 记录左右括号个数

// falg 标志输入是否合法

char Exp[254];

int i = 0;

int cnt1 = 0;

int cnt2 = 0;

int flag = 0;

printf("input equation:\n");

gets(Exp);

char stdinput[17] = {'+','-','*','/','(',')','1','2','3','4','5','6','7','8','9','0','\0'};

while(Exp[i]!='\0'){

if(Exp[i]=='(') cnt1++;

if(Exp[i]==')') cnt2++;

if(!In(Exp[i],stdinput)) {flag = 1; break;}

else i++;

}

if(cnt1!=cnt2) flag = 1;

if(!flag) {printf("结果:%f",EvaluateExpression(Exp));}

else {printf("invalid input\n");}

}

5. 程序的层次结构

程序结构.png

五、用户手册

本程序的运行环境为DOS操作系统,执行文件为:calculation.exe

进入程序按提示操作,输入表达式

输入后按回车符即显示结果

六、测试结果

(1) (((6+6)*6+3)*2+6)*2

测试结果.png

七、源代码

calculation.c

#include

#include

#include

#include

#include

#define STACK_INIT_SIZE 1000

#define STACKNCREMENT 10

typedef struct {

char *base;

char *top;

int stacksize;

}TRStack;

typedef struct {

float *base;

float *top;

int stacksize;

}NDStack;

char TRGetTop(TRStack *S){

char e;

if(S->top == S->base) return 0;

e = *(S->top-1);

return e;

}

float NDGetTop(NDStack *S){

float e;

if(S->top == S->base) return 0;

e = *(S->top-1);

return e;

}

int InitTRStack(TRStack *S){

S->base = (char *)malloc(STACK_INIT_SIZE * sizeof(char));

if(!S->base) exit(-2);

S->top = S->base;

S->stacksize = STACK_INIT_SIZE;

return 1;

}

int InitNDStack(NDStack *S){

S->base = (float *)malloc(STACK_INIT_SIZE * sizeof(float));

if(!S->base) exit(-2);

S->top = S->base;

S->stacksize = STACK_INIT_SIZE;

return 1;

}

int TRPush(TRStack *S, char e){

if(S->top - S->base >= S->stacksize){

S->base = (char *)realloc(S->base, (S->stacksize + STACK_INIT_SIZE * sizeof(char)));

if(!S->base) exit(-2);

S->top = S->base + S->stacksize;

S->stacksize += STACKNCREMENT;

}

*S->top++ = e;

return 1;

}

int NDPush(NDStack *S, float e){

if(S->top - S->base >= S->stacksize){

S->base = (float *)realloc(S->base, (S->stacksize + STACK_INIT_SIZE * sizeof(float)));

if(!S->base) exit(-2);

S->top = S->base + S->stacksize;

S->stacksize += STACKNCREMENT;

}

*S->top++ = e;

return 1;

}

int TRPop(TRStack *S, char *e){

if(S->top == S->base) return 0;

*e = * --S->top;

return 1;

}

int NDPop(NDStack *S, float *e){

if(S->top == S->base) return 0;

*e = * --S->top;

return 1;

}

float Opreate(float a, float b, char theta){

switch(theta){

case'+':return a+b;

case'-':return a-b;

case'/':return a/b;

case'*':return a*b;

default:return 0;

}

}

int In(char c,char *OP){

int flag = 0;

int i = 0;

while(OP[i]!='\0'){

if(OP[i]==c) flag=1;

i++;

}

return flag;

}

char Precede(char m, char n, char *OP){

unsigned char Prior[7][7] =

{'>','>','','>',

'>','>','','>',

'>','>','>','>','','>',

'>','>','>','>','','>',

'

'>','>','>','>',' ','>','>',

'

int i = 0; int j = 0;

while(m != OP[i]) i++;

while(n != OP[j]) j++;

return Prior[i][j];

}

int OutPutNDStack(NDStack *S){

float *c;

c = S->top;

printf("OPND栈: ");

while(c!=S->base){

c--;

printf("%f ",*c);

}

}

int OutPutTRStack(TRStack *S){

char *c;

c = S->top;

printf("OPTR栈: ");

while(c!=S->base){

c--;

printf("%c ",*c);

}

}

float EvaluateExpression(char *expr){

char OP[8] = {'+','-','*','/','(',')','#','\0'};

TRStack OPTR; NDStack OPND;

char *c;

char End[] = {'#','\0'};

char cc[254];

float a,b;

char theta,x;

float cf;

InitTRStack(&OPTR); TRPush(&OPTR,'#');

InitNDStack(&OPND); c = strcat(expr,End);

while(*c!='#' || TRGetTop(&OPTR)!='#') {

if(!In(*c,OP)){

while(!In(*c,OP)){strcat(cc,c);c++;}

cf = atof(cc);

OutPutTRStack(&OPTR);

OutPutNDStack(&OPND);

printf("输入字符:%f ",cf);

memset(cc, 0x00, sizeof (char) * 256);

NDPush(&OPND,cf);

printf("操作:Push(OPND,%f)\n",cf);

}

else{

OutPutTRStack(&OPTR);

OutPutNDStack(&OPND);

printf("输入字符:%c ",*c);

switch(Precede(TRGetTop(&OPTR),*c,OP)){

case'

TRPush(&OPTR,*c);

printf("操作:Push(OPTR,%c)\n",*c);

c++;

break;

case'=':

TRPop(&OPTR,&x);

printf("操作:Pop(OPTR,%c)\n",x);

c++;

break;

case'>':

TRPop(&OPTR,&theta);

NDPop(&OPND,&b);

NDPop(&OPND,&a);

NDPush(&OPND,Opreate(a,b,theta));

printf("操作:Opreate(%f,%c,%f)\n",a,theta,b);

break;

}

}

}

OutPutTRStack(&OPTR);

OutPutNDStack(&OPND);

printf("输入字符:%c ",*c);

printf("操作:return GetTop(OPND)\n");

return NDGetTop(&OPND);

}

int main(){

char Exp[254];

int i = 0;

int cnt1 = 0;

int cnt2 = 0;

int flag = 0;

printf("input equation:\n");

gets(Exp);

char stdinput[17] = {'+','-','*','/','(',')','1','2','3','4','5','6','7','8','9','0','\0'};

while(Exp[i]!='\0'){

if(Exp[i]=='(') cnt1++;

if(Exp[i]==')') cnt2++;

if(!In(Exp[i],stdinput)) {flag = 1; break;}

else i++;

}

if(cnt1!=cnt2) flag = 1;

if(!flag) {printf("结果:%f",EvaluateExpression(Exp));}

else {printf("invalid input\n");}

}

linux算术表达式求值数据结构,数据结构:算数表达式求值演示相关推荐

  1. 数据结构——整数算数表达式

    实现要求: (1) 以字符序列的形式从终端输入语法正确的.不含变量的整数表达式.利用 下表给出的算符优先关系,实现对算术混合运算表达式的求值,并仿照求值中运 算符栈.运算数栈.输入字符和主要操作的变化 ...

  2. 如何利用计算机求函数解析式,数据结构表达式求值(计算器)实验报告(共10篇).doc...

    数据结构表达式求值(计算器)实验报告(共10篇) 数据结构表达式求值(计算器)实验报告(共10篇) 数据结构课程设计_实验报告(一)表达式求值(计算器) 数据结构课程设计 实验报告 起止时间:2015 ...

  3. 表达式求值问题数据结构课程设计

    完整代码在最后~~ 1 需求分析 1.1 问题描述 表达式求值是程序设计语言编译中的一个最基本问题,就是将一个表达式转化为逆波兰表达式并求值.具体要求是以字符序列的形式从终端输入语法正确的.不含变量的 ...

  4. c语言程序设计报告表达式求值,数据结构 课程设计表达式求值 实验报告

    <数据结构 课程设计表达式求值 实验报告>由会员分享,可在线阅读,更多相关<数据结构 课程设计表达式求值 实验报告(21页珍藏版)>请在人人文库网上搜索. 1.实验课程名称 级 ...

  5. java求值不用后缀表达式_数据结构之后缀表达式求值(java实现)

    数据结构之后缀表达式求值(java实现) 前记 ​ 今天在刷leet code的时候刷到了一道题,后缀表达式(逆波兰表达式)求值,我花了一会儿写了一下它的解法.但是今天我不谈什么是后缀表达式,有兴趣的 ...

  6. c语言中缀表达式求值_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)

    第三章:栈和队列 下面讲解栈的应用主要内容有:栈的应用.括号匹配.中 后 前 缀表达式转换 1.栈的应用 1.1括号匹配 我们在数学运算中 [(A+b)*c] - (E-F) 往往都会有[ ] 和 ( ...

  7. 【数据结构】中缀表达式转前缀表达式求值

    中缀表达式转前缀表达式求值 首先将中缀表达式转换成前缀表达式 前缀表达式中,操作符在前 例如:1+2*(5-3)+4 后缀表达式:++1*2-534 一.转换思路 转换思路为将输入的中缀表达式字符串从 ...

  8. 表达式求值问题 数据结构_【每日一题51】实际问题与一次函数 看图象求表达式 由表达式求值...

    关注"中考数学当百荟",感谢您的支持! 51.如图,折线MNP表示汽车耗油量y与速度x之间的关系,其中30≤x≤120.已知线段NP表示函数关系中,速度每增加1 km/h,耗油量增 ...

  9. 栈的应用-算数表达式求值

    List item ** 实验要求** 河 南 师 范 大 学 20学年-21学年第 1 学期 数据结构实验任务书 专业名称: 实验学时: 4 课程名称:数据结构 任课教师: 王亚丽 实验题目:栈的应 ...

最新文章

  1. Ant Design Pro 登录流程以及路由权限设置
  2. 如何通过远程修改另一台电脑注册表
  3. 推荐IronPython开发IDE: IronPython Studio
  4. libcusolver.so.8.0: cannot open shared object file: No such file or director
  5. linux存储--linux内存分配图(九)
  6. linux对目录进行操作,Linux 基础:对文件和目录进行操作的 Linux 和 Unix 命令 笔记...
  7. Tails 3.0 正式发布,不再支持 32 位计算机
  8. 页描述符 linux,有关Crontab导致Linux文件描述符...-探讨:crond 引发大量sendmail进...-linux下的ulimit命令用法解析(图文)_169IT.COM...
  9. linux五周第三次课(3月7日)笔记
  10. XShell免费版的安装配置教程以及使用教程(超级详细、保姆级)
  11. Silverlight游戏设计(Game Design):(十四)练习用游戏素材资源的获取及相关工具使用心得...
  12. 五色电阻在线计算机,五色环电阻阻值在线计算一键生成计算器
  13. Kali linux 2016.2(Rolling)里Metasploit连接(包括默认和自定义)的PostgreSQL数据库之后的切换到指定的工作空间...
  14. hiveql 没有left()right()函数,可用substr()替代
  15. SpringCloud学习笔记(五)服务发现Discovery
  16. 桌面以及文件资源管理器无限重启的解决
  17. python手机app开发_H5 手机 App 开发入门:技术篇
  18. 麋鹿分布图制作(一)——调用百度API查询地名的坐标
  19. Camshift的优点与缺点
  20. Posix API 与 网络协议栈 详细介绍

热门文章

  1. strncmp很好的函数
  2. 最常用的13条mysql语句
  3. 给年轻程序员的几句话
  4. WCF开发框架形成之旅--WCF应用常见问题处理
  5. powerbuilder9.0 一对多输入框架和查询报表框架(PFC) 数据库2000
  6. 通过编程为ASP.NET页面设置缓存
  7. python中functools_python–functools的使用 | 学步园
  8. java中1代表什么,java中iamp; =(i-1)的含义是什么
  9. html模块开发模板引擎,一个前端html模板处理引擎(javascript)
  10. vs html自动对齐,vscode esLint 保存时 自动对齐