数据结构-算术表达式求值(含需求分析和源代码)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
需求分析(附代码)
一、需求分析
(1)首先定义两个栈OPTR、OPND,栈OPTR用于存放运算符,栈OPND 用于存放操作数;定义一个一维数组expr【】存放表达式串。
(2)主函数主要包括两部分:(1)判断运算符优先权,返回优先权高的;(2)操作函数。
(3)开始将‘#’入操作符栈,通过一个函数来判别算术运算符的优先级。且规定‘#’的优先级最低。在输入表达式的最后输入‘#’,代表表达式输入结束。在表达式输入过程中,遇操作数则直接入栈。遇到运算符则与栈顶运算符比较优先级,当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
(4)最初实现的加、减、乘、除及带小括号的基本运算,但考虑到实用性,后来的设计中有加上了乘方运算。在乘方运算中借用了C库中自带的乘方函数pow。
二、概要设计
1、设定栈的抽象数据类型定义:
ADT Stack {
数据对象:
D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 }
数据关系:
R1={
约定an 端为栈顶,a1 端为栈底。
基本操作:
InitStack(&S)
操作结果:构造一个空栈S。
DestroyStack(&S)
初始条件:栈S 已存在。
操作结果:栈S 被销毁。
StackEmpty(S)
初始条件:栈S 已存在。
操作结果:若栈S 为空栈,则返回TRUE,否则FALE。StackLength(S)
初始条件:栈S 已存在。
操作结果:返回S 的元素个数,即栈的长度。
GetTop(S, &e)
初始条件:栈S 已存在且非空。操作结果:用e 返回S 的栈顶元素。ClearStack(&S)
初始条件:栈S 已存在。
操作结果:将S 清为空栈。
Push(&S, e)
初始条件:栈S 已存在。
操作结果:插入元素e 为新的栈顶元素。
Pop(&S)
初始条件:栈S 已存在且非空。
操作结果:删除S 的栈顶元素,并用e 返回其值。
} ADT Stack
2、表达式的抽象数据类型
ADT arithmetic
{
数据对象:D1={‘+’、‘-’、‘*’、‘/’、‘#’,‘^’}
D2={ a1 a2 a3 a4 ……}
基本操作:
int In(int c)
//判断输入字符c是否为运算符,返回1,则c为操作符,返回0则c不是操作符
char precede(int top,char c)
//判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘<’,当前一个运算符为‘(’当前运算符为‘)’时返回‘=’,用于去除表达式的括号。elemtype operate(elemtype a,char theta,elemtype b)
//计算运算过程中的两个数的值,a,b为两个操作数,theta为操作符,成功,返回两个数的运算结果
elemtype evaluate(struct Sqstack opnd,struct Sqstack optr)
//求表达式的值的整个操作过程,通过调用相应的函数实现遇到运算符则与栈顶运算符比较优先级,当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
}
3、本程序包含的模块:
(1)、主程序模块
void main()
{
struct Sqstack opnd;//操作数栈
struct Sqstack optr;//操作符栈
elemtype result;
result=evaluate(opnd,optr);
printf("the result is %d\n",result);
}
(2)运算模块——实现数据表达式的运算
(3)栈模块——实现栈抽象数据类型
模块调用关系:
5、计算表达式的伪码
初始化操作符栈
将‘#’入操作符栈
初始化操作数栈
输入字符c
while(c!='#'||gettop(optr)!='#')
{
如果c是操作数
{
如果flag=1;
将操作数栈的栈顶元素出栈,和c共同转化为相应的int类型的数后入操作数栈若flag=0
则将c-48入操作数栈
flag=1;
输入c
}
否则{
将c和操作符栈的栈顶元素比较
若c的优先级高于栈顶元素
C入操作符栈
输入下一个字符c
若为c与栈顶元素是一对括号,
则将栈顶元素出栈
输入下一字符c
若c的优先级低于栈顶元素
则计算操作数栈的栈顶的两个元素的运算,后将运算结果入栈
}
}//while
三、详细设计
1、输入字符为char类型
栈结构
struct Sqstack
{
elemtype *top; //栈顶指针
elemtype *base; //栈底指针
int stacksize; //栈的大小
};
2、栈的基本操作
(1)初始化栈
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;