数据结构-算术表达式求值(含需求分析和源代码)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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={ | ai-1, ai∈D, i=2,...,n }

约定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;

相关文档
最新文档