当前位置:
文档之家› 数据结构(表达式求值)课程设计
数据结构(表达式求值)课程设计
8
#*(
3 5
)#
CPop(OPF)
9
#*
3 5
#
Operate(‘3’,’*’,5’)
10
#
15
#
Return(GetTop(OPS))
表一
4.4.
附录一:测试数据
组别
表达式
正确值
1
12+(9-8)*7-(-6*5)
49
2
3.14*(67.305-65.305)+3.14
9.42
3
3+{2*[2*(3+4)]}
1.首先置操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素;
2.依次读入表达式,若是操作符即进OPS栈,若是运算符则和OPF栈的栈顶运算符比较优先权后作相应的操作,直至整个表达式求值完毕(即OPF栈的栈顶元素和当前读入的字符均为”#”)。
4.
4.1
本程序所做的工作为:能直接求出四则表达式的值,并输出;本程序可用于小学教师对学生作业的快速批改以及对数值位数要求较大的科学运算。
2
#
3
*(7-2)#
CPush(OPF,’*’)
3
#*
3
(7-2)#
CPush(OPF,’(’)
4
#*(
3
7-2)#
Push(OPS,’7’)
5
#*(
3 7
-2)#
CPush(OPF,’-’)
6
#*(-
3 7
2)#
Push(OPS,’2’)
7
#*(-
3 7 2
)#
Operate(‘7’,’-’,’2’)
{if(运算符为‘-’&&运算符前一个为‘(’)
{c=*p;
temp=p;
p++;
}
else
{调用函数CGetTop(OPF,ch)得到OPF的栈顶元素;
switch(调用函数Precede(ch,c)判断栈顶元素与接收的字符的优生级别)
{
case栈顶运算符优先权低:
调用函数CPush(OPF,c)将c入运算符栈;
操作结果:用e返回head的栈顶元素
(6)CDestroyStack(LinkCharStack &head)
初始条件:栈head已存在
操作结果:栈head被销毁
}ADT LinkCharStack
3.系统中子程序及功能要求:
Comop(char ch):判断输入的字符是否为运算符
char Precede(char ch,char c):比较两个运算符的优先级,ch是栈顶字符,c是表达式字符。
}//else1
}//else2
}//退出最外层while循环
调用函数GetTop(OPS,i)得到栈顶元素i;
将两个栈消毁;
}EvaluateExpression函数结束
利用该算法对算术表达式3*(7-2)求值操作过程如下:
步骤
OPF栈
OPS栈
输入表达式
主要操作
1
#
3*(7-2)#
Push(OPS,’3’)
while(p指针不指向’.’)
{
将p指向的字符转为小数n
p--;
}
p=q;
p++;
}
if(运算符为‘-’并且运算符前一个为‘(’或者为表达式的开始)
调用Push(OPS,-(m+n))将m+n的相反数入栈;
else
调用Push(OPS,m+n)将m+n入栈;
}数字进栈结束
else//是运算符时则进栈OPF
定义一个运算符栈OPF;
定义一个操作数栈OPS;
调用函数InitStack()初始化栈OPS;
调用函数CInitCharStack()初始化栈OPF;
调用函数CPush(OPF,'#')将#压入运算符栈;
c=*p;temp=p;p++;
if(第一个字符就为‘-’)
{
c=*p;temp=p;p++;
}
接收下一个字符;
case栈顶运算符优先权高:
运算符出栈得到ch;
数字栈连续出栈两次得到a,b ;
调用Operate(a,ch,b)并将结果入栈到数字栈;break;
case优生权相等:脱括号并接收下一个字符;
调用CPop(OPF,ch)脱括号;接收下一个字符;
default:接收下一个字符;
}退出switch循环
31
4
4.3-{2.5*[9.9/(1.1+2.2)]}
-3.2
5
12-(3-6*7)8-4
错误表达式
表二
按照附录中的测试数据,得出如下测试、分析结果:
当我们输入表格中两个正确的四则表达式时程序能准确地求得其值:
完全支持浮点数,正负数的运算;
而当我们输入第五组错误的表达式时,程序能做出正确判断,提醒用户输入的表达式错误。
操作结果:构造一个空栈head
(2)CIsEmpty(LinkCharStack head)
初始条件:栈head已存在
操作结果:若栈为空栈,则返回TRUE,否则FALSE
(3)CPush(LinkCharStack &head,ElementType element)
初始条件:栈head已存在
操作结果:插入元素element为新的栈顶元素
ElementType Operate(ElementType a,char ch,ElementType b):解析表达式中的双目运算,其返回的结果即为双目运算表达式的值。
int error(char *str):错误提示函数,实现对多种非法四则表达式的判断,并给出提示,让用户更正自己的输入错误。
子程序7可调用子程序1,2,3,4。
4.3.
此算法的基本思想:
首先置操作数栈OPS为空栈,表达式起始符“#”为运算符的栈底元素;依次读入表达式中每个字符,若是操作数则进栈,若是运算符则和OPF栈的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕(即OPF栈的栈顶元素和当前读入的字符均为“#”)
# include <string.h>
#define ERROR 0
#define OK 1
#defineTRUE 1
#define FALSE 0
typedef char ElemType;
typedef int Status;
typedef double ElementType;
typedef int Status;
void InitStack(LinkStack &head){
head=(LinkStack)malloc(sizeof(StackNode));
初始条件:栈head已存在且非空
操作结果:删除head的栈顶元素,并用e返回其值
(5)GetTop(LinkStack head, ElementType &element)
初始条件:栈head已存在并且非空
操作结果:用e返回head的栈顶元素
(6)DestroyStack(LinkStack &head)
# define STACK_INIT_SIZE 30
# define STACKINCREAMENT 10
# define NUMBER 30
typedef struct node{
ElementType data;
struct node *next;
}StackNode, *LinkStack;
初始条件:栈head已存在
操作结果:若栈为空栈,则返回TRUE,否则FALSE
(3)Push(LinkStack &head,ElementType element)
初始条件:栈head已存在
操作结果:插入元素element为新的栈顶元素
(4)Pop(LinkStack &head,ElementType &element)
初始条件:栈head已存在
操作结果:栈head被销毁
}ADT LinkStack
2.//用于存储运算符(OPF):
ADT LinkCharStack{
数据对象D:元素类型为字符型的符号字符
数据关系R:
基本操作:栈中数据元素之间是线性关系。
(1)CInitStack(LinkCharStack &head)
void MenuPrint():主菜单打印函数。
void Clear():清屏函数。
ElementType EvaluateExpression(char *exp):这是此程序的核心函数,可以综合其它子函数,实现最终的表达式求解。
各程序模块之间的调用关系(子程序编号见上):
主函数可调用子程序5,6,7。
程序设计时,也不要怕遇到错误,在实际操作过程中犯的一些错误还会有意外的收获,感觉课程设计很有意思。在具体操作中这学期所学的数据结构的理论知识得到巩固,达到课程设计的基本目的,也发现自己的不足之出,在以后的上机中应更加注意。
6.
//这个栈是用来存储数字字符的
#include<stdlib.h>
# include <stdio.h>
课程设计报告
课程名称:
数据结构课程设计
课程设计题目:
表达式求值问题
姓名:
系:
计算机科学与技术
专业:
计算机科学与技术
年级:
2011级
学号:
指导教师:
职称: