数据结构算术表达式求值.docx

上传人:b****7 文档编号:23924073 上传时间:2023-05-22 格式:DOCX 页数:23 大小:18.92KB
下载 相关 举报
数据结构算术表达式求值.docx_第1页
第1页 / 共23页
数据结构算术表达式求值.docx_第2页
第2页 / 共23页
数据结构算术表达式求值.docx_第3页
第3页 / 共23页
数据结构算术表达式求值.docx_第4页
第4页 / 共23页
数据结构算术表达式求值.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

数据结构算术表达式求值.docx

《数据结构算术表达式求值.docx》由会员分享,可在线阅读,更多相关《数据结构算术表达式求值.docx(23页珍藏版)》请在冰豆网上搜索。

数据结构算术表达式求值.docx

数据结构算术表达式求值

二课程设计2——算术表达式求值

一、需求分析

二、程序的主要功能

三、程序运行平台

四、数据构造

五、算法及时间复杂度

六、测试用例

七、程序源代码

三感想体会与总结

算术表达式求值

一、需求分析

一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。

假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、完毕符“*〞,如:

*〔7+15〕*〔23-28/4〕*。

引入表达式起始、完毕符是为了方便。

编程利用“算符优先法〞求算术表达式的值。

二、程序的主要功能

〔1〕从键盘读入一个合法的算术表达式,输出正确的结果。

〔2〕显示输入序列和栈的变化过程。

三、程序运行平台

VisualC++6.0版本

四、数据构造

本程序的数据构造为栈。

〔1〕运算符栈局部:

structSqStack//定义栈

{

char*base;//栈底指针

char*top;//栈顶指针

intstacksize;//栈的长度

};

intInitStack(SqStack&s)//建立一个空栈S

{

if(!

(s.base=(char*)malloc(50*sizeof(char))))

e*it(0);

s.top=s.base;

s.stacksize=50;

returnOK;

}

charGetTop(SqStacks,char&e)//运算符取栈顶元素

{

if(s.top==s.base)//栈为空的时候返回ERROR

{

printf("运算符栈为空!

\n");

returnERROR;

}

else

e=*(s.top-1);//栈不为空的时候用e做返回值,返回S的栈顶元素,并返回OK

returnOK;

}

intPush(SqStack&s,chare)//运算符入栈

{

if(s.top-s.base>=s.stacksize)

{

printf("运算符栈满!

\n");

s.base=(char*)realloc(s.base,(s.stacksize+5)*sizeof(char));//栈满的时候,追加5个存储空间

if(!

s.base)e*it(OVERFLOW);

s.top=s.base+s.stacksize;

s.stacksize+=5;

}

*(s.top)++=e;//把e入栈

returnOK;

}

intPop(SqStack&s,char&e)//运算符出栈

{

if(s.top==s.base)//栈为空栈的时候,返回ERROR

{

printf("运算符栈为空!

\n");

returnERROR;

}

else

{

e=*--s.top;//栈不为空的时候用e做返回值,删除S的栈顶元素,并返回OK

returnOK;

}

}

intStackTraverse(SqStack&s)//运算符栈的遍历

{

char*t;

t=s.base;

if(s.top==s.base)

{

printf("运算符栈为空!

\n");//栈为空栈的时候返回ERROR

returnERROR;

}

while(t!

=s.top)

{

printf("%c",*t);//栈不为空的时候依次取出栈元素

t++;

}

returnERROR;

}

(2)数字栈局部:

structSqStackn//定义数栈

{

int*base;//栈底指针

int*top;//栈顶指针

intstacksize;//栈的长度

};

intInitStackn(SqStackn&s)//建立一个空栈S

{

s.base=(int*)malloc(50*sizeof(int));

if(!

s.base)e*it(OVERFLOW);//存储分配失败

s.top=s.base;

s.stacksize=50;

returnOK;

}

intGetTopn(SqStackns,int&e)//数栈取栈顶元素

{

if(s.top==s.base)

{

printf("运算数栈为空!

\n");//栈为空的时候返回ERROR

returnERROR;

}

else

e=*(s.top-1);//栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OK

returnOK;

}

intPushn(SqStackn&s,inte)//数栈入栈

{

if(s.top-s.base>=s.stacksize)

{

printf("运算数栈满!

\n");//栈满的时候,追加5个存储空间

s.base=(int*)realloc(s.base,(s.stacksize+5)*sizeof(int));

if(!

s.base)e*it(OVERFLOW);

s.top=s.base+s.stacksize;//插入元素e为新的栈顶元素

s.stacksize+=5;

}

*(s.top)++=e;//栈顶指针变化

returnOK;

}

intPopn(SqStackn&s,int&e)//数栈出栈

{

if(s.top==s.base)

{

printf("运算符栈为空!

\n");//栈为空栈的视时候,返回ERROR

returnERROR;

}

else

{

e=*--s.top;//栈不空的时候,则删除S的栈顶元素,用e返回其值,并返回OK

returnOK;

}

}

intStackTraversen(SqStackn&s)//数栈遍历

{

int*t;

t=s.base;

if(s.top==s.base)

{

printf("运算数栈为空!

\n");//栈为空栈的时候返回ERROR

returnERROR;

}

while(t!

=s.top)

{

printf("%d",*t);//栈不为空的时候依次输出

t++;

}

returnERROR;

}

五、算法及时间复杂度

1、算法:

建立两个不同类型的空栈,先把一个‘*’压入运算符栈。

输入一个算术表达式的字符串〔以‘*’完毕〕,从第一个字符依次向后读,把读取的数字放入数字栈,运算符放入运算符栈。

判断新读取的运算符和运算符栈顶得运算符号的优先级,以便确定是运算还是把运算符压入运算符栈。

最后两个‘*’遇到一起则运算完毕。

数字栈顶的数字就是要求的结果。

2、时间复杂度:

O(n)

数据压缩存储栈,其操作主要有:

建立栈intPush(SeqStack*S,char*)

入栈intPop(SeqStack*S,char*)

出栈。

以上各操作运算的平均时间复杂度为O(n),其主要时间是消耗在输入操作。

六、测试用例

如下图。

最终结果如下图:

七、源代码

/**************************************************************************************************

第七题算术表达式求值

[问题描述]

一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。

假设操作数是正整数,

运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、完毕符“*〞,

如:

*〔7+15〕*〔23-28/4〕*。

引入表达式起始、完毕符是为了方便。

编程利用“算符优先法〞求算术表达式的值。

[根本要求]

〔1〕从键盘读入一个合法的算术表达式,输出正确的结果。

〔2〕显示输入序列和栈的变化过程。

***************************************************************************************************/

*include

*include

*include

*include

*include

*include

*defineOK1

*defineERROR0

*defineSTACK_INIT_SIZE100

//*defineSTACKINCREMENT10

//========================================================

//以下定义两种栈,分别存放运算符和数字

//========================================================

//*******************运算符栈局部*************************

structSqStack//定义栈

{

char*base;//栈底指针

char*top;//栈顶指针

intstacksize;//栈的长度

};

intInitStack(SqStack&s)//建立一个空栈S

{

if(!

(s.base=(char*)malloc(50*sizeof(char))))

e*it(0);

s.top=s.base;

s.stacksize=50;

returnOK;

}

charGetTop(SqStacks,char&e)//运算符取栈顶元素

{

if(s.top==s.base)//栈为空的时候返回ERROR

{

printf("运算符栈为空!

\n");

returnERROR;

}

else

e=*(s.top-1);//栈不为空的时候用e做返回值,返回S的栈顶元素,并返回OK

returnOK;

}

intPush(SqStack&s,chare)//运算符入栈

{

if(s.top-s.base>=s.stacksize)

{

printf("运算符栈满!

\n");

s.base=(char*)realloc(s.base,(s.stacksize+5)*sizeof(char));//栈满的时候,追加5个存储空间

if(!

s.base)e*it(OVERFLOW);

s.top=s.base+s.stacksize;

s.stacksize+=5;

}

*(s.top)++=e;//把e入栈

returnOK;

}

intPop(SqStack&s,char&e)//运算符出栈

{

if(s.top==s.base)//栈为空栈的时候,返回ERROR

{

printf("运算符栈为空!

\n");

returnERROR;

}

else

{

e=*--s.top;//栈不为空的时候用e做返回值,删除S的栈顶元素,并返回OK

returnOK;

}

}

intStackTraverse(SqStack&s)//运算符栈的遍历

{

char*t;

t=s.base;

if(s.top==s.base)

{

printf("运算符栈为空!

\n");//栈为空栈的时候返回ERROR

returnERROR;

}

while(t!

=s.top)

{

printf("%c",*t);//栈不为空的时候依次取出栈元素

t++;

}

returnERROR;

}

//**********************数字栈局部***************************

structSqStackn//定义数栈

{

int*base;//栈底指针

int*top;//栈顶指针

intstacksize;//栈的长度

};

intInitStackn(SqStackn&s)//建立一个空栈S

{

s.base=(int*)malloc(50*sizeof(int));

if(!

s.base)e*it(OVERFLOW);//存储分配失败

s.top=s.base;

s.stacksize=50;

returnOK;

}

intGetTopn(SqStackns,int&e)//数栈取栈顶元素

{

if(s.top==s.base)

{

printf("运算数栈为空!

\n");//栈为空的时候返回ERROR

returnERROR;

}

else

e=*(s.top-1);//栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OK

returnOK;

}

intPushn(SqStackn&s,inte)//数栈入栈

{

if(s.top-s.base>=s.stacksize)

{

printf("运算数栈满!

\n");//栈满的时候,追加5个存储空间

s.base=(int*)realloc(s.base,(s.stacksize+5)*sizeof(int));

if(!

s.base)e*it(OVERFLOW);

s.top=s.base+s.stacksize;//插入元素e为新的栈顶元素

s.stacksize+=5;

}

*(s.top)++=e;//栈顶指针变化

returnOK;

}

intPopn(SqStackn&s,int&e)//数栈出栈

{

if(s.top==s.base)

{

printf("运算符栈为空!

\n");//栈为空栈的视时候,返回ERROR

returnERROR;

}

else

{

e=*--s.top;//栈不空的时候,则删除S的栈顶元素,用e返回其值,并返回OK

returnOK;

}

}

intStackTraversen(SqStackn&s)//数栈遍历

{

int*t;

t=s.base;

if(s.top==s.base)

{

printf("运算数栈为空!

\n");//栈为空栈的时候返回ERROR

returnERROR;

}

while(t!

=s.top)

{

printf("%d",*t);//栈不为空的时候依次输出

t++;

}

returnERROR;

}

//========================================================

//以下定义函数

//========================================================

intIsoperator(charch)//判断是否为运算符,分别将运算符和数字进入不同的栈

{

switch(ch)

{

case'+':

case'-':

case'*':

case'/':

case'(':

case')':

case'*':

return1;

default:

return0;

}

}

intOperate(inta,charop,intb)//运算操作

{

intresult;

switch(op)

{

case'+':

result=a+b;

break;

case'-':

result=a-b;

break;

case'*':

result=a*b;

break;

case'/':

result=a/b;

break;

}

returnresult;

}

charPrecede(charch1,charch2)//运算符优先级的比拟

{

charp;

switch(ch1)

{

case'+':

case'-':

if(ch2=='+'||ch2=='-'||ch2==')'||ch2=='*')

p='>';//ch1运算符的优先级小于ch2运算符

else

p='<';

break;

case'*':

case'/':

if(ch2=='(')

p='<';

else

p='>';

break;

case'(':

if(ch2==')')

p='=';

elseif(ch2=='*')

{

printf("表达式错误!

运算符不匹配!

\n");

e*it(0);

}

else

p='<';

break;

case')':

if(ch2=='(')

{

printf("表达式错误!

运算符不匹配!

\n");

e*it(0);

}

else

p='>';

break;

case'*':

if(ch2==')')

{

printf("表达式错误!

运算符不匹配!

\n");

e*it(0);

}

elseif(ch2=='*')

p='=';

else

p='<';

break;

}

returnp;

}

//========================================================

//以下是求值过程

//========================================================

intEvaluateE*pression()//参考书p53算法3.4

{

inta,b,temp,answer;

charch,op,e;

char*str;

intj=0;

SqStacknOPND;//OPND为运算数字栈

SqStackOPTR;//OPTR为运算符栈

InitStack(OPTR);

Push(OPTR,'*');//,所以此栈底是'*',因为运算符栈以'*'作为完毕标志

InitStackn(OPND);

//printf("\n\n按任意键开场求解:

\n\n");

//ch=getch();

printf("\n请输入表达式并以'*'完毕:

\n");

str=(char*)malloc(50*sizeof(char));

gets(str);

ch=str[j];//ch是字符型的,而e是整型的整数

j++;

GetTop(OPTR,e);//e为栈顶元素返回值

while(ch!

='*'||e!

='*')

{

if(!

Isoperator(ch))//遇到数字,转换成十进制并计算

{

temp=ch-'0';//将字符转换为十进制数

ch=str[j];

j++;

while(!

Isoperator(ch))

{

temp=temp*10+ch-'0';//将逐个读入运算数的各位转化为十进制数

ch=str[j];

j++;

}

Pushn(OPND,temp);

}

elseif(Isoperator(ch))//判断是否是运算符,不是运算符则进栈

switch(Precede(e,ch))

{

case'<':

Push(OPTR,ch);//栈顶元素优先权低

ch=str[j++];

printf("\n\n运算符栈为:

\n");//输出栈,显示栈的变化

StackTraverse(OPTR);

printf("\n运算数栈为:

\n");

StackTraversen(OPND);

break;

case'=':

Pop(OPTR,op);//脱括号并接收下一字符

ch=str[j++];

printf("\n\n运算符栈为:

\n");

StackTraverse(OPTR);

printf("\n数栈为:

\n");

StackTraversen(OPND);

break;

case'>':

Pop(OPTR,op);//弹出最上面两个,并运算,把结果进栈

Popn(OPND,b);

Popn(OPND,a);

Pushn(OPND,Operate(a,op,b));

printf("\n\n运算符栈为:

\n");

StackTraverse(OPTR);

printf("\n数栈为:

\n");

StackTraversen(OPND);

}

else

{

printf("您的输入有问题,请检查重新输入!

");

e*it(0);

}

GetTop(OPTR,e);//取出运算符栈最上面元素是否是'*'

}//while

GetTopn(OPND,answer);//已输出。

数字栈最上面即是最终结果

returnanswer;

}

//========================================================

//执行局部

//========================================================

voidShowMenu()

{

printf("\n\n");

printf("███████████████████████████████████████\n");

printf("████\n");

printf("██表达式求值系统██\n");

printf("████\n");

printf("████████████████████

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 药学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1