算法表达式语法检查(数据结构课程设计)

合集下载

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告

课程设计报告题目:算术表达式求值一、需求分析1、设计要求:给定一个算术表达式,通过程序求出最后的结果1>、从键盘输入要求解的算术表达式;2>、采用栈结构进行算术表达式的求解过程;3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果;2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。

在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。

在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。

在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。

如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。

二、概要设计1、本程序包含的模块:(1)栈模块——实现栈抽象数据类型(2)运算模块——实现数据表达式的运算(3)主程序模块三、详细设计(1)栈模块1、定义栈结构struct Sqstack{elemtype *top;//栈顶元素elemtype *base; //栈底元素int stacksize;//栈的大小};2、栈的基本操作①初始化栈status initstack(struct Sqstack &s){s.base=(elemtype *)malloc(stack_size*sizeof(elemtype)); if(!s.base)return OVERFLOW;s.top=s.base;s.stacksize=stack_size;return OK;}②入栈status push(struct Sqstack &s,elemtype e){if(s.top-s.base>=s.stacksize){s.base=(elemtype*)realloc(s.base,(s.stacksize+stack_increase ment)*sizeof(elemtype));if(!(s.base))return OVERFLOW;s.top=s.base+s.stacksize;s.stacksize+=stack_increasement;}* s.top++=e;return OK;}③出栈elemtype pop(struct Sqstack &s){elemtype e;if(s.top= =s.base)return ERROR;e=*--s.top;return e;}④取栈顶元素elemtype gettop(struct Sqstack &s){elemtype e;if(s.top==s.base)return ERROR;e=*(s.top-1);return e;}(2)运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0int In(int c){char p[10]="+-*/()#^";int i=0;while(p[i]!='\0'){if(p[i]==c)return 1;i++;}return 0;}2、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘<’,当前一个运算符为‘(’当前运算符为‘)’时返回‘=’,用于去除表达式的括号。

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用数据结构课程设计目录一、需求分析1、设计要求:本程序需要实现对算术表达式的求解功能,可以支持基本的四则运算,包括加、减、乘、除,同时还需要支持括号的使用。

2、设计构想:我们将使用栈来实现算术表达式的求解。

具体地,我们将把中缀表达式转换为后缀表达式,然后再利用栈来求解后缀表达式。

二、概要设计1、本程序包含的模块:本程序包含两个模块:中缀表达式转后缀表达式模块和后缀表达式求解模块。

三、详细设计1、定义栈结构我们定义一个栈结构,用来存储算术表达式中的运算符和操作数。

具体地,栈中的每个元素都包含两个属性:元素的值和元素的类型。

元素的值可以是一个数字或一个运算符,元素的类型可以是数字或运算符。

我们使用一个数组来实现栈的结构。

为了方便起见,我们还需要定义一些基本的栈操作,如入栈、出栈、判断栈是否为空等。

2、栈的基本操作栈是一种常见的数据结构,具有后进先出(LIFO)的特点。

栈的基本操作包括初始化栈、入栈、出栈、取栈顶元素和运算模块。

1) 初始化栈初始化栈是指将栈的各项属性设置为初始状态。

通常包括将栈顶指针设为-1,表示栈为空。

2) 入栈入栈是指将元素压入栈顶。

入栈操作需要将栈顶指针加1,并将元素存入栈顶位置。

3) 出栈出栈是指将栈顶元素弹出。

出栈操作需要将栈顶元素取出,并将栈顶指针减1.4) 取栈顶元素取栈顶元素是指获取栈顶元素的值,但不将其弹出。

取栈顶元素操作只需要返回栈顶元素的值即可。

5) 运算模块栈可以用于实现各种运算,例如中缀表达式的转换和计算、括号匹配等。

运算模块需要根据具体需求进行设计和实现。

3、判断运算符的优先级在进行中缀表达式的转换和计算时,需要判断运算符的优先级。

通常采用栈来实现这一功能。

具体实现方法是将运算符入栈,当遇到新的运算符时,将其与栈顶运算符进行比较,如果新运算符的优先级高于栈顶运算符,则将其入栈,否则将栈顶运算符弹出并输出,直到新运算符可以入栈为止。

算法分析与设计数据结构实践课程设计

算法分析与设计数据结构实践课程设计

算法分析与设计数据结构实践课程设计1. 课程简介本课程旨在让学生了解算法分析与设计的基本概念,理解数据结构的各种操作原理和实现方式,掌握基础的算法设计技巧和算法分析方法,并实践运用所学知识解决实际问题。

2. 课程设计要求2.1 实践项目本课程设计要求学生设计一个实践项目,项目内容可以是任何与数据结构相关的实际问题。

同时,要求学生采用所学的算法分析与设计方法,设计和实现一个高效、正确、可靠的解决方案,并进行评估和测试。

2.2 项目报告学生需要撰写一份详细的项目报告,内容包括但不限于:•项目背景和问题描述•解决方案设计思路和方法•程序实现细节和代码结构说明•性能测试和评估结果分析•可能的改进和优化建议2.3 课程答辩学生需要在课程结束前,进行项目答辩。

答辩内容包括但不限于:•项目背景和问题描述•解决方案设计思路和方法•程序实现细节和代码结构说明•性能测试和评估结果分析•学生自己的总结和评估3. 简要算法分析与设计3.1 算法分析算法分析是评估一个算法效率的方法,通常使用时间复杂度和空间复杂度等指标来衡量。

时间复杂度表示算法的运行时间和问题规模之间的关系,空间复杂度表示算法需要占用的内存空间大小和问题规模之间的关系。

常见的算法分析方法包括递归求解、迭代求解和分治法等。

3.2 算法设计算法设计是指解决问题的过程中,构建一个高效、正确、可靠的计算机程序的方法。

通常使用问题建模、设计思维和常用算法等工具来完成。

常见的算法设计方法包括贪心算法、动态规划、分支界定法等。

同时,为了有效提高算法效率,通常需要采用数据结构等相关工具。

4. 数据结构简介数据结构是计算机科学中的重要基础,它是指将数据和相应的操作进行组织的方法。

数据结构可以分为线性结构和非线性结构,线性结构包括栈、队列和链表等,非线性结构包括树和图等。

数据结构的选择通常依据问题的特点和算法需求来考虑。

常见的数据结构包括数组、链表、栈、队列、树、图等。

5. 结语算法分析与设计和数据结构实践是计算机科学中的重要基础,它们与计算机科学的其他领域息息相关。

数据结构课程设计报告-表达式求值

数据结构课程设计报告-表达式求值

《数据结构》课程设计利用栈求表达式的值班级: 2学号: 100171021330姓名:吴迪指导老师:王方利用栈求表达式的值1、设计思路这个程序的关键是对数字与运算符的判断和运算符优先级的判断,以及出栈的运算。

建立两个栈,分别存储数字与运算符,栈1存运算符,栈2存数字。

依次读取表达式的字符串,先判断是数字还是运算符,如果是数字不能马上压入栈2,因为可能是大于10的数字,应该继续循环,如果还是数字,则利用计算保存数值,直到指到运算符时停止,将计算后的数字压入栈2。

压入运算符之前先将要压入的与栈顶的运算符优先级相比较,如果栈顶是‘(’而当前不是‘)’,则不需比较优先级,直接压入;如果栈顶是‘(’,当前是‘)’,则抵消(弹出‘(’,指向表达式下一个字符);若当前的运算符优先级大于栈顶的,则压入;若当前的运算符优先级小于栈內时,弹出栈顶的运算符,同时弹出两组数字,经过运算符的运算后再重新压到栈内。

为了方便判断运算结束,在存储运算符之前先将‘#’压入栈1中,在输入表达式时以‚#‛结束,所以可以以运算符==‘#’并且栈1顶==‘#’来结束运算,弹出栈2的数值,即为表达式求值的最终结果。

上述操作的算法步骤:(1)初始化算符S1,数字栈S2;,将‘#’压入算符栈S1中。

(2)读表达式字符=>w。

(3)当栈顶为‘#’并且w也是‘#’时结束;否则循环做下列步骤:(3-1)如果w是数字,存储到m,再经过计算存储到num中。

m=w-‘0’;num=num*pow(10,n)+m;n++;读下一个字符=>w,如果是运算符,则跳出循环;转3-2。

(3-2)w若是运算符,则:(3-2-1)如果栈顶为‘(’并且w为‘)’则‘(’出栈,读下一个字符=>w;转(3)。

(3-2-2)如果栈顶为‘(’或者栈顶优先级小于w优先级,则w入栈,读下一个字符=>w;转(3)。

否则:从算符栈中出栈,并从数字栈中弹出两组数字进行运算,将结果重新压入数字栈,转(3)。

算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告

《数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用目录一、需求分析 (3)1、设计要求: (3)2、设计构想: (3)二、概要设计 (4)1、本程序包含的模块: (4)三、详细设计 (4)1、定义栈结构 (5)2、栈的基本操作 (5)(1)初始化栈 (5)(2)入栈 (5)(3)出栈 (6)(4)取栈顶元素 (6)(5)运算模块 (6)3、判断运算符的优先级 (7)4、运算函数 (8)(1) 基础运算函数: (8)(2)运算函数 (9)(3)主程序模块 (12)四、调试分析 (12)1、测试结果 (12)2、程序时间复杂度为O(n); (13)3、设计中出现的问题: (13)4、算法改进: (14)五、课程设计总结 (15)课程设计报告一、需求分析1、设计要求:给定一个算术表达式,通过程序求出最后的结果1>、从键盘输入要求解的算术表达式;2>、采用栈结构进行算术表达式的求解过程;3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果;2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。

在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。

在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。

在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。

如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。

二、概要设计1、本程序包含的模块:(1)栈模块——实现栈抽象数据类型(2)运算模块——实现数据表达式的运算(3)主程序模块三、详细设计(1)栈模块1、定义栈结构struct Sqstack{int *top;//栈顶元素int *base; //栈底元素int stacksize;//栈的大小};2、栈的基本操作(1)初始化栈int initstack(struct Sqstack &s){s.base=(int *)malloc(stack_size*sizeof(int));if(!s.base)return OVERFLOW;s.top=s.base;s.stacksize=stack_size;return OK;}(2)入栈int push(struct Sqstack &s,int e){if(s.top-s.base>=s.stacksize){s.base=(int*)realloc(s.base,(s.stacksize+stack_increasement)*sizeof(int));if(!(s.base))return OVERFLOW;s.top=s.base+s.stacksize;s.stacksize+=stack_increasement;}* s.top++=e;return OK;}(3)出栈int pop(struct Sqstack &s){int e;if(s.top==s.base)return ERROR;e=*--s.top;return e;}(4)取栈顶元素int gettop(struct Sqstack &s){int e;if(s.top==s.base)return ERROR;e=*(s.top-1);return e;}(5)运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0int In(int c){char p[10]="+-*/()#^";int i=0;while(p[i]!='\0'){if(p[i]==c)return 1;i++;}return 0;}3、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回'>',前一个运算符小于当前运算符的优先级则返'<',当前一个运算符为'('当前运算符为')'时返回'=',用于去除表达式的括号。

数据结构课程设计-表达式求值【完整版】

数据结构课程设计-表达式求值【完整版】

XXXXXX大学《数据结构》课程设计报告班级:学号:姓名:指导老师:目录一算术表达式求值一、需求分析二、程序得主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结算术表达式求值一、需求分析一个算术表达式就是由操作数(operand)、运算符(operator)与界限符(delimiter)组成得。

假设操作数就是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号与表达式起始、结束符“#”,如:#(7+15)*(23—28/4)#。

引入表达式起始、结束符就是为了方便.编程利用“算符优先法”求算术表达式得值.二、程序得主要功能(1)从键盘读入一个合法得算术表达式,输出正确得结果。

(2)显示输入序列与栈得变化过程。

三、程序运行平台Visual C++6、0版本四、数据结构本程序得数据结构为栈。

(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针intstacksize; //栈得长度};intInitStack (SqStack &s) //建立一个空栈S{if (!(s、base= (char *)malloc(50*sizeof(char))))exit(0);s、top=s、base;s、stacksize=50;return OK;}char GetTop(SqStack s,char &e) //运算符取栈顶元素{if (s、top==s、base) //栈为空得时候返回ERROR{ﻩ printf("运算符栈为空!\n");ﻩ return ERROR;}elsee=*(s、top-1); //栈不为空得时候用e做返回值,返回S得栈顶元素,并返回OK returnOK;}int Push(SqStack&s,char e) //运算符入栈{if (s、top—s、base >= s、stacksize)ﻩ{printf("运算符栈满!\n");ﻩs、base=(char*)realloc(s、base,(s、stacksize+5)*sizeof(char));//栈满得时候,追加5个存储空间if(!s、base)exit (OVERFLOW);s、top=s、base+s、stacksize;s、stacksize+=5;}ﻩ*(s、top)++=e;//把e入栈ﻩreturn OK;}int Pop(SqStack &s,char &e) //运算符出栈{if (s、top==s、base) //栈为空栈得时候,返回ERROR{printf("运算符栈为空!\n”);ﻩ return ERROR;}else{ﻩﻩe=*-—s、top;//栈不为空得时候用e做返回值,删除S得栈顶元素,并返回OK return OK;}}int StackTraverse(SqStack&s)//运算符栈得遍历{ﻩchar *t;ﻩt=s、base;ﻩif (s、top==s、base){ﻩ printf(”运算符栈为空!\n”); //栈为空栈得时候返回ERRORreturn ERROR;}while(t!=s、top){ﻩﻩprintf(" %c",*t); //栈不为空得时候依次取出栈内元素t++;ﻩ}return ERROR;}(2)数字栈部分:struct SqStackn//定义数栈{int *base; //栈底指针int*top; //栈顶指针int stacksize; //栈得长度};intInitStackn (SqStackn &s) //建立一个空栈S{s、base=(int*)malloc(50*sizeof(int));if(!s、base)exit(OVERFLOW);//存储分配失败s、top=s、base;s、stacksize=50;return OK;}int GetTopn(SqStackn s,int&e) //数栈取栈顶元素{if(s、top==s、base){printf("运算数栈为空!\n");//栈为空得时候返回ERRORﻩ return ERROR;}elseﻩe=*(s、top-1);//栈不为空得时候,用e作返回值,返回S得栈顶元素,并返回OKreturnOK;}int Pushn(SqStackn &s,int e) //数栈入栈{if(s、top—s、base>=s、stacksize){ﻩﻩprintf("运算数栈满!\n");//栈满得时候,追加5个存储空间ﻩs、base=(int*)realloc (s、base,(s、stacksize+5)*sizeof(int));if(!s、base) exit (OVERFLOW);ﻩs、top=s、base+s、stacksize;//插入元素e为新得栈顶元素s、stacksize+=5;}*(s、top)++=e; //栈顶指针变化returnOK;}int Popn(SqStackn &s,int &e)//数栈出栈{ﻩif (s、top==s、base){ﻩ printf("运算符栈为空!\n");//栈为空栈得视时候,返回ERRORﻩ return ERROR;ﻩ}else{ﻩﻩe=*—-s、top;//栈不空得时候,则删除S得栈顶元素,用e返回其值,并返回OK ﻩreturnOK;}}int StackTraversen(SqStackn &s)//数栈遍历{ﻩint*t;ﻩt=s、base ;ﻩif(s、top==s、base)ﻩ{printf("运算数栈为空!\n”);//栈为空栈得时候返回ERRORﻩ return ERROR;ﻩ}ﻩwhile(t!=s、top)ﻩ{printf(” %d”,*t); //栈不为空得时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。

数据结构课程设计四则运算表达式求值(C语言版)

数据结构课程设计四则运算表达式求值(C语言版)

数据结构课程设计四则运算表达式求值(C语⾔版) 明⼈不说暗话,直接上,输⼊提取码z3fy即可下载。

⽂件中包含程序,程序运⾏⽂件,设计报告和测试样例,应有尽有,欢迎⼩伙伴们在中下载使⽤。

本课程设计为四则运算表达式求值,⽤于带⼩括号的⼀定范围内正负数的四则运算标准(中缀)表达式的求值。

注意事项:1、请保证输⼊的四则表达式的合法性。

输⼊的中缀表达式中只能含有英⽂符号“+”、“-”、“*”、“/”、“(”、“)”、“=”、数字“0”到“9”以及⼩数点“.”,输⼊“=”表⽰输⼊结束。

例如9+(3-1)*3.567+10/2=,特别是请勿输⼊多余空格和中⽂左右括号。

2、输⼊的中缀表达式默认限定长度是1001,可根据具体情况调整字符串数组的长度。

3、请保证输⼊的操作数在double数据类型范围内,单个数字有效数字长度不可超过15位。

本课程设计中操作数是C语⾔中的双精度浮点数类型。

4、本课程设计中的运算数可以是负数,另外如果是正数可直接省略“+”号(也可带“+”号)。

 下⾯的程序正常运⾏需要在上⾯的百度⽹盘中下载相应⽂件,否则⽆法正常使⽤哦。

1/*本程序为四则运算表达式求值系统,⽤于计算带⼩括号的四则运算表达式求值。

2具体算法:3先将字符串处理成操作单元(操作数或操作符),再利⽤栈根据四则运算4的运算法则进⾏计算,最后得出结果。

*/56 #include<stdio.h>7 #include<ctype.h>8 #include<stdlib.h>9 #include<string.h>10 #include<stdlib.h>11 #include<ctype.h>1213const int Expmax_length = 1001;//表达式最⼤长度,可根据适当情况调整14struct Ope_unit15 {//定义操作单元16int flag;//=1表⽰是操作数 =0表⽰是操作符 -1表⽰符号单元17char oper;//操作符18double real;//操作数,为双精度浮点数19 };2021void Display();//菜单22void Instru(); //使⽤说明23int Check(char Exp_arry[]);24void Evalua(); //先调⽤Conver操作单元化,再调⽤Calculate函数计算结果并输出25int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//将字符串处理成操作单元26int Isoper(char ch);//判断合法字符(+ - * / ( ) =)27int Ope_Compar(char ope1,char ope2);//操作符运算优先级⽐较28double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//⽤栈计算表达式结果29double Four_arithm(double x,double y,char oper);//四则运算3031int main()32 {33int select;34while(1)35 {36 Display();37 printf("请输⼊欲执⾏功能对应的数字:");38 scanf("%d",&select);39 printf("\n");40switch(select)41 {42case1: Evalua(); break;43case2: Instru(); break;44case0: return0;45default : printf("⽆该数字对应的功能,请重新输⼊\n");46 system("pause");47 }48 }49return0;50 }5152int Check(char Exp_arry[])53 {//检查是否有⾮法字符,返回1表⽰不合法,0表⽰合法54int Explength=strlen(Exp_arry),i;55for(i=0;i<Explength;i++)56 {57if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))58return1;59if(isdigit(Exp_arry[i]))60 {61int Dig_number=0,Cur_positoin=i+1;62while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')63 {64 Dig_number++;65 Cur_positoin++;66 }67if(Dig_number >= 16)//最多能够计算15位有效数字68return1;69 }70 }71return0;72 }7374void Evalua()75 {//先调⽤Conver函数将字符串操作单元化,再调⽤Calculate函数计算结果并输出76char Exp_arry[Expmax_length];77int flag=0;//假设刚开始不合法,1表达式合法,0不合法78struct Ope_unit Opeunit_arry[Expmax_length];7980 getchar();//吃掉⼀个换⾏符81 printf("请输⼊四则运算表达式,以=结尾:\n");82 gets(Exp_arry);83 flag=Check(Exp_arry);84if(flag)85 printf("该表达式不合法!\n");86else87 {88int Opeunit_count = Conver(Opeunit_arry,Exp_arry);89double ans = Calculate(Opeunit_arry,Opeunit_count,flag);90if(flag)91 {92 printf("计算结果为:\n");93 printf("%s%lf\n",Exp_arry,ans);94 }95else96 printf("该表达式不合法!\n");97 }98 system("pause");99 }100101int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])102 {//将字符串操作单元化103int Explength=strlen(Exp_arry);104int i,Opeunit_count=0;105for(i=0;i<Explength;i++)106 {107if(Isoper(Exp_arry[i]))//是操作符108 {109 Opeunit_arry[Opeunit_count].flag=0;110 Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];111 }112else//是操作数113 {114 Opeunit_arry[Opeunit_count].flag=1;115char temp[Expmax_length];116int k=0;117for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++)118 {119 temp[k++]=Exp_arry[i];120 }121 i--;122 temp[k]='\0';123 Opeunit_arry[Opeunit_count].real=atof(temp);//将字符转化为浮点数124125//负数126if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0127 && Opeunit_arry[Opeunit_count-1].oper=='-')128 {129 Opeunit_arry[Opeunit_count-1].flag = -1;130 Opeunit_arry[Opeunit_count].real *= -1;131 }// -9132if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0133 && Opeunit_arry[Opeunit_count-1].oper=='-' && Opeunit_arry[Opeunit_count-2].flag==0 134 && Opeunit_arry[Opeunit_count-2].oper !=')')135 {136 Opeunit_arry[Opeunit_count-1].flag = -1;137 Opeunit_arry[Opeunit_count].real *= -1;138 }// )-9139140//正数141if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0142 && Opeunit_arry[Opeunit_count-1].oper=='+')143 {144 Opeunit_arry[Opeunit_count-1].flag = -1;145 }// +9146if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0147 && Opeunit_arry[Opeunit_count-1].oper=='+' && Opeunit_arry[Opeunit_count-2].flag==0148 && Opeunit_arry[Opeunit_count-2].oper !=')')149 {150 Opeunit_arry[Opeunit_count-1].flag = -1;151 }// )+9152 Opeunit_count++;153 }154 }155/*for(i=0;i<Opeunit_count;i++)156 {//查看各操作单元是否正确,1是操作数,0是操作符157 if(Opeunit_arry[i].flag == 1)158 printf("该单元是操作数为:%lf\n",Opeunit_arry[i].real);159 else if(Opeunit_arry[i].flag == 0)160 printf("该单元是操作符为:%c\n",Opeunit_arry[i].oper);161 else162 printf("该单元是负号符为:%c\n",Opeunit_arry[i].oper);163 }*/164return Opeunit_count;165 }166167double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)168 {//根据运算规则,利⽤栈进⾏计算169int i,dS_pointer=0,oS_pointer=0;//dS_pointer为操作数栈顶指⽰器,oS_pointer为操作符栈顶指⽰器170double Dig_stack[Expmax_length];//操作数栈(顺序存储结构)171char Ope_stack[Expmax_length];//操作符栈172173for(i=0;i<Opeunit_count-1;i++)174 {175if( Opeunit_arry[i].flag != -1 )176 {177if(Opeunit_arry[i].flag)//是操作数178 {179 Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//⼊操作数栈180//printf("%lf\n",Digit[dS_pointer-1]);181 }182else//是操作符 + - * / ( )183 {184//操作符栈为空或者左括号⼊栈185if(oS_pointer==0 || Opeunit_arry[i].oper=='(')186 {187 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;188//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);189 }190else191 {192if(Opeunit_arry[i].oper==')')//是右括号将运算符⼀直出栈,直到遇见左括号193 {194 oS_pointer--;//指向栈顶195 dS_pointer--;//指向栈顶196while(Ope_stack[oS_pointer] != '(' && oS_pointer != 0)197 {198 Dig_stack[dS_pointer-1] = Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 199 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈200201 dS_pointer--;//前⼀个操作数出栈202//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);203 }204 oS_pointer--;//左括号出栈205206 oS_pointer++;//恢复指向栈顶之上207 dS_pointer++;208 }209else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-1]))//和栈顶元素⽐较210 {211 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;212//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);213 }214else//运算符出栈,再将该操作符⼊栈215 {216 oS_pointer--;//指向栈顶217 dS_pointer--;//指向栈顶218while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])==0 && oS_pointer != -1) 219 {//当前操作符⽐栈顶操作符优先级⾼220 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 221 Ope_stack[oS_pointer--]);222 dS_pointer--;223//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);224 }225 oS_pointer++;//恢复指向栈顶之上226 dS_pointer++;227 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;228 }229 }230 }231 }232 }233/*for(i=0;i<oS_pointer;i++)234 printf("操作符栈%oS_pointer\Ope_u_count",Operator[i]);235 for(i=0;i<dS_pointer;i++)236 printf("操作数栈%lf\n",Digit[i]);*/237 oS_pointer--;//指向栈顶元素238 dS_pointer--;//指向栈顶元素239while(oS_pointer != -1)240 {241 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 242 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈243 dS_pointer--;//前⼀个操作数出栈244//printf("操作数栈顶元素为%lf\Ope_u_count",Digit[dS_pointer]);245 }246//printf("%dS_pointer,%dS_pointer\n",oS_pointer,dS_pointer);247if(oS_pointer==-1 && dS_pointer==0)248 flag=1;//为1表⽰表达式合法249return Dig_stack[0];250 }251252int Ope_Compar(char ope1,char ope2)253 {//操作符运算优先级⽐较254char list[]={"(+-*/"};255int map[5][5]={//先⾏后列,⾏⽐列的运算级优先级低为0,⾼为1256// ( + - * /257/* ( */1,0,0,0,0,258/* + */1,0,0,0,0,259/* - */1,0,0,0,0,260/* * */1,1,1,0,0,261/* / */1,1,1,0,0 };262int i,j;263for(i=0;i<5;i++)264if(ope1==list[i]) break;265for(j=0;j<5;j++)266if(ope2==list[j]) break;267return map[i][j];268 }269270double Four_arithm(double x,double y,char oper)271 {//四则运算272switch(oper)//保证不含其它运算符273 {274case'+': return x+y;275case'-': return x-y;276case'*': return x*y;277case'/': return x/y;//y不能为0278default : return0;279 }280 }281282int Isoper(char ch)283 {//判断合法字符 + - * / ( ) =284if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=')285return1;286return0;287 }288289void Display()290 {//打印菜单291 system("cls");292 printf("/******************************************************************************/\n");293 printf("\t\t 欢迎使⽤本四则运算表达式求值系统\n");294 printf("\n\t说明:建议请您先阅读使⽤说明,再输⼊相应的数字进⾏操作,谢谢配合!\n"); 295 printf("\n\t\t1 四则运算表达式求值\n");296 printf("\n\t\t2 使⽤说明\n");297 printf("\n\t\t0 退出\n");298 printf("/******************************************************************************/\n");299 }300301void Instru()302 {//打印使⽤说明303 FILE *fp;304char ch;305if( ( fp=fopen("使⽤说明.txt","r") ) == NULL)306 {307 printf("⽂件打开失败!\n");308 exit(0);309 }310for(; (ch = fgetc(fp)) != EOF; )311 putchar(ch);312 fclose(fp);313 printf("\n");314 system("pause");315 }。

编译原理课程设计--算术表达式的语法分析及语义分析程序设计 精品

编译原理课程设计--算术表达式的语法分析及语义分析程序设计 精品

课程设计任务书学生姓名:专业班级:指导教师:工作单位:题目: 算术表达式的语法分析及语义分析程序设计1.目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

2.设计内容及要求算术表达式的文法:(1)选择算符优先分析法完成以上任务,中间代码选用逆波兰式。

(2)写出算术表达式的符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。

(3)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

3.课程设计报告书的内容应包括:(1)设计题目、班级、学号、姓名、完成日期;(2)给出算术表达式的语法分析和语义分析的设计。

(3)简要的分析与概要设计;(4)详细的算法描述;(5)源程序清单;(6)给出软件的测试方法和测试结果;(7)设计的评价、收获与体会。

时间安排:第18周,周1-周3下午,周5全天指导教师签名:年月日系主任(或责任教师)签名:年月日1 课设要求设计题目算术表达式转换成逆波兰式(用算符优先分析法)1.1课程设计的目的课程设计是对学生的一种全面综合训练,是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。

通常,设计题中的问题比平时的练习题要复杂,也更接近实际。

编译原理这门课程安排的课程设计的目的是旨在要求学生进一步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容,选择合适的数据逻辑结构表示问题,然后编制算法和程序完成设计要求,从而进一步培养学生独立思考问题、分析问题、解决实际问题的动手能力。

要求学生在上机前应认真做好各种准备工作,熟悉机器的操作系统和语言的集成环境,独立完成算法编制和程序代码的编写。

1.2 设计内容及要求算术表达式的文法:〈无符号整数〉∷=〈数字〉{〈数字〉}〈标志符〉∷=〈字母〉{〈字母〉|〈数字〉}〈表达式〉∷= [+|-]〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标志符〉|〈无符号整数〉|‘(’〈表达式〉‘)’〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/1.选择算符优先分析法完成以上任务,中间代码选用逆波兰式。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中南民族大学计算机科学学院课程设计报告课程数据结构题目算法表达式语法检查年级 2014专业软件工程学生柳真学号 201421092073指导教师刘赛2015年12月20 日中南民族大学计算机科学学院本科课程设计任务书设计名称:算术表达式语法检查指导教师:下达时间: 2015-11-30 学生姓名:学号:年级专业: 2014级软件工程一、课程设计的基本要求利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用C/C++语言进行程序设计,并规范地完成课程设计报告。

通过课程设计,巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。

具体要求如下:1、对现实复杂问题中的数据对象特性及组织方法进行分析和研究,设计适当的数据逻辑结构、存贮结构以及相应运算操作,把现实世界问题建模转化为计算机内部表示并进行处理。

2、采取模块化方式进行程序设计,要求程序的功能设计、数据结构设计及整体结构设计合理。

学生也可根据自己对题目的理解增加新的功能模块(视情况可另外加分)。

3、系统以菜单界面方式(至少采用文本菜单界面,如能采用图形菜单界面更好)工作,运行界面友好,演示程序以用户和计算机的对话方式进行,利用文件进行数据的提取与存储。

4、程序算法说明清晰,理论分析与计算正确,运行情况良好,实验测试数据无误,容错性强(能对错误输入进行判断控制)。

5、编程风格良好(包括缩进、空行、适当注释、变量名和函数名见名知意,程序容易阅读等);6、写出规范的课程设计报告,具体要求见相关说明文档。

二、课程设计的主要内容题目描述:算术表达式语法检查。

功能要求及说明:(1)键盘读入一个四则运算算术表达式,对其进行语法检查;(2)算术表达式允许嵌套,如果出错,指出出错位置;(3)不需要计算结果;(4)尽量不使用栈。

三、课程设计的进程安排1.2015年11月30日:布置并下达课程设计题目。

2.2015年12月7日之前:联系指导教师,理解课程设计题目及相关要求,查阅相关资料,进行课程设计(地点:9-204,9-206)。

3.2015年12月7日至12月31日(第15周-第18周):课程设计源程序的调试、修改与检查,书写课程设计报告(地点:计算机科学学院实验机房)。

4.2016年12月31日之前:上交、检查设计报告(地点:计算机科学学院实验机房)。

指导教师:2015年 11月20日算术表达式语法检查一目的根据课题要求,完成算法表达式语法检查。

具体完成以下四点要求:(1)键盘读入一个四则运算算术表达式,对其进行语法检查;(2)算术表达式允许嵌套,如果出错,指出出错位置;(3)不需要计算结果;(4)尽量不使用栈。

二需求分析1、选择存放算术表达式的数据结构本次课设,我选择了本学期数据结构中所学的栈来实现算术表达式中的字符存放。

2、运算符优先级划分一个完整的算术表达式中包含+、-、*、/、(、)六种运算符,当遇到这些字符时要确定其优先级的高低,并依次存放进栈或者出栈。

并且还可以进行发现输入错误提示判断,达到课题中相关要求。

三概要设计1、运算符优先级等级划分表上表中1代表栈中运算符出栈,进行运算;0代表栈中运算符(‘(’或‘#’)出栈;-1代表当前运算符进栈;-2代表当前输入‘)’错误;-3代表算术表达式末尾少输入‘)’。

2、程序流程图四详细设计1、栈的结构及相关功能函数构造伪代码typedef int SElemType;const int STACK_INIT_SIZE = 100; //存储空间初始分配量const int STACKINCREMENT = 10; //存储空间分配增量typedef struct{SElemType *base; // 栈底指针,在栈构造前和销毁后,其值均为空SElemType *top; //栈顶指针int stacksize; //当前已分配的存储空间}SqStack;//构造一个空栈void InitStack(SqStack &S);//若栈不为空,返回栈顶元素值SElemType GetTop(SqStack & S);//插入元素e为栈的新栈顶元素void push(SqStack &S,SElemType e);//用e返回栈顶元素,并删除栈顶元素void Pop(SqStack &S,SElemType &e);2、实现表达式语法检查功能函数构造伪代码//判定输入的运算符,并分类标记int judgePrecedence(char a){int i = 7;switch(a){case '+': i = 0; break;case '-': i = 1; break;case '*': i = 2; break;case '/': i = 3; break;case '(': i = 4; break;case ')': i = 5; break;case '#': i = 6; break;}return i;}//比较运算符的优先级,并标记分类int Precedence(char a,char b){根据judgePrecedence()函数确定a、b的运算符种类,然后构建一个7*7的二维数组表,依次填入优先级,并返回相应优先等级。

具体表格信息见概要设计中运算符优先等级划分表。

}//执行运算int Operate(int a,char b,int c){其中a、c是数字,b是运算符(+、-、*、/),实现具体运算操作,并返回运算结果值。

}//判断c是否是运算符int panduan(char c){根据judgePrecedence()函数,判断c是否是运算符,如果是怎返回1,否则返回0。

}//具体应用操作void Yunsuan(){SqStack A,B; //创建栈A、Bpush(B,'#'); //栈B中栈底存入#c = getchar(); //获取算术表达式中字符int i = 1;while(c !='#' || GetTop(B)!='#'){if(i == 1 && judgePrecedence(c) != 7)首字符是运算符,报错;if(c >= '0' && c <= '9')字符是数字,存放在数组d[100]中,后转化为数字存入栈A中;else if(judgePrecedence(c) != 7)字符是运算符,进行判断,有错则报错,没有则进栈B;else报错,输入非法字符。

}}五调试分析1、算法逻辑问题及输出错误检查一个算术表达式错误时,要具体要第几位以及是哪些错误,在刚开始的检查功能检查设计的时候,我的代码只能检查到+、-、*、/相关输入错误,对于(、)运算符不能完全检查出输入错误,其中有关除数为0的输入错误时,程序不能检查除数0后面表达式中的错误,直接程序终止。

后来,我在程序加了一个条件关于除数为0的运算限定,成功解决了除数为0后面表达式的语法无法检查的问题。

其中,最为重要的是,通过设计不同类型的算术表达式进行语法检查,不断地发现程序设计过程中的逻辑错误,并不断修改,最后成功解决了本次课设中难点。

六测试结果1、设计输入的算术表达式(1) +-*/1+2/(4-4*2/4)(2) (3a+2b)*4-8/2(3) a!c1+2a*(3-4/2)(4) 1++2—3*(4//5)(5) 1+2*(2*4/0-3)(6) 1+2*(3-4/2(7) 1-2/((3-4*2)(8) 2*3+)(3/3-4)(9) 2++4-5*(3+2+((2*1)(10) (2++4))-5/0*(3+2*(2+1)2、具体运算检查分析结果截图图一:上图一是设计输入的算术表达式(1)—(4)运行结果截图;图二:上图二是设计输入的算术表达式(5)—(8)运行结果截图;图三:上图三是输入设计的算术表达式(9)—(10)运行结果截图。

七用户使用说明1、输入规则输入一个算术表达式,其中对应的运算符是+、-、*、/、(、)表达的意思是加、减、乘、除、顺括号、反括号。

要求输入一个算术表达式完毕后,在输入一个‘#’结束输入,最后按enter键即可得到算术表达式语法检查结果。

八课程设计总结在本次课程设计实施的过程中,遇到了很多问题,当然收获也很多。

起初,让我感觉很难的地方在于如何确定算术表达式错误的位置以及有哪些错误要确定。

在此过程中,我用了一个整形变量来计算依次检查的字符数,来确定错误的具体位置。

其中错误的类型要分类进行查找,在算法实施之前我把错误类型进行分类,并初步画出算法的程序流程图,不断反复推敲和检查,从中也发现了我很多逻辑上的错误。

通过不断修改和测试,也让我设计的核心功能函数不断完善,最终达到课题的要求。

附具体源码:#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;typedef int SElemType;const int STACK_INIT_SIZE = 100; //存储空间初始分配量const int STACKINCREMENT = 10; //存储空间分配增量typedef struct{SElemType *base; // 栈底指针,在栈构造前和销毁后,其值均为空SElemType *top; //栈顶指针int stacksize; //当前已分配的存储空间}SqStack;//构造一个空栈void InitStack(SqStack &S);//若栈不为空,返回栈顶元素值SElemType GetTop(SqStack & S);//插入元素e为栈的新栈顶元素void push(SqStack &S,SElemType e);//用e返回栈顶元素,并删除栈顶元素void Pop(SqStack &S,SElemType &e);//判定输入的运算符,并分类标记int judgePrecedence(char a);//比较运算符的优先级,并标记分类int Precedence(char a,char b);//执行运算int Operate(int a,char b,int c);//判断c是否是运算符int panduan(char c);//具体应用操作void Yunsuan();int main(){while(1){cout<<"请输入算术表达式(按#结束):";Yunsuan();/* cout<<"继续输入算术表达式请输入$,退出请输入#:"<<endl;char i;cin>>i;if(i == '#' )break;*/}return 0;}void InitStack(SqStack &S){S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));S.top = S.base;S.stacksize = STACK_INIT_SIZE;return ;}SElemType GetTop(SqStack & S){if(S.top == S.base) return 0;return *(S.top-1);}void push(SqStack &S,SElemType e){if(S.top - S.base >= S.stacksize){S.base = (SElemType * )realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(SElemType));if(!S.base) exit(0);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return ;}void Pop(SqStack &S,SElemType &e){if(S.top == S.base) return ;e = * --S.top;return ;}int judgePrecedence(char a){int i = 7;switch(a){case '+': i = 0; break;case '-': i = 1; break;case '*': i = 2; break;case '/': i = 3; break;case '(': i = 4; break;case ')': i = 5; break;case '#': i = 6; break;}return i;}int Precedence(char a,char b){int i,j;i = judgePrecedence(a);j = judgePrecedence(b);int Pre[7][7] = {{1,1,-1,-1,-1,1,1},{1,1,-1,-1,-1,1,1},{1,1,1,1,-1,1,1},{1,1,1,1,-1,1,1},{-1,-1,-1,-1,-1,0,-3},{1,1,1,1,-1,1,1},{-1,-1,-1,-1,-1,-2,0} };if(Pre[i][j] == 1)return 1;else if(Pre[i][j] == -1)return -1;else if(Pre[i][j] == -2)return -2;else if(Pre[i][j] == -3)return -3;elsereturn 0;}int Operate(int a,char b,int c){switch(b){case '+': return a+c; break;case '-': return a-c; break;case '*': return a*c; break;case '/':if(c == 0)return 1;elsereturn a/c;break;}return 0;}int panduan(char c){int i = 0;if(judgePrecedence(c) != 7)i = 1;return i;}void Yunsuan(){SqStack A,B;int a,b,e;char c,d[100];InitStack(A);InitStack(B);push(B,'#');c = getchar();int i = 1;while(c !='#' || GetTop(B)!='#'){int t = 0;if(i == 1 && judgePrecedence(c) != 7){if(judgePrecedence(c) == 4){push(B,c);c = getchar();++i;}else{cout<<"第1位输入"<<c<<"错误"<<endl;c = getchar();++i;while(panduan(c)){cout<<"第"<<i<<"位输入"<<c<<"错误"<<endl;c = getchar();++i;}}}if(c >= '0' && c <= '9'){while(c >= '0' && c <= '9'){d[t++] = c;c = getchar();++i;}d[t] = '\0';a = atoi(d); //字符型转换为整形push(A,a);}else if(judgePrecedence(c) != 7){if(judgePrecedence(c) == 4){cout<<"第"<<i<<"位输入"<<c<<"错误"<<endl;c = getchar();++i;while(panduan(c)){cout<<"第"<<i<<"位输入"<<c<<"错误"<<endl;c = getchar();++i;}break;}b = Precedence(GetTop(B),c);switch(b){case 1:Pop(A,b);Pop(A,a);Pop(B,e);if(e == '/' && b == 0)cout<<"第"<<(i-1)<<"位非法输入,除数不能为0"<<endl;push(A,Operate(a,e,b));break;case -1:push(B,c);c = getchar();++i;if(c == ')'){cout<<"第"<<i<<"位输入"<<c<<"错误"<<endl;c =getchar();++i;}if(c == '('){push(B,c);c = getchar();++i;}while(panduan(c)){cout<<"第"<<i<<"位输入"<<c<<"错误"<<endl;c = getchar();++i;}break;case 0:Pop(B,e);c =getchar();++i;break;case -2:cout<<"第"<<i<<"位输入"<<c<<"错误"<<endl;c = getchar();++i;break;case -3:Pop(B,e);cout<<"第"<<i<<"位少输入)"<<endl;break;}}else{cout<<"第"<<i<<"位非法输入"<<c<<endl;c = getchar();++i;}}c = getchar();cout<<"算术表达式语法检查完毕,已退出";cout<<endl<<endl;}。

相关文档
最新文档