数据结构课程设计用栈求表达式.docx

上传人:b****7 文档编号:16448076 上传时间:2023-07-13 格式:DOCX 页数:29 大小:40.66KB
下载 相关 举报
数据结构课程设计用栈求表达式.docx_第1页
第1页 / 共29页
数据结构课程设计用栈求表达式.docx_第2页
第2页 / 共29页
数据结构课程设计用栈求表达式.docx_第3页
第3页 / 共29页
数据结构课程设计用栈求表达式.docx_第4页
第4页 / 共29页
数据结构课程设计用栈求表达式.docx_第5页
第5页 / 共29页
数据结构课程设计用栈求表达式.docx_第6页
第6页 / 共29页
数据结构课程设计用栈求表达式.docx_第7页
第7页 / 共29页
数据结构课程设计用栈求表达式.docx_第8页
第8页 / 共29页
数据结构课程设计用栈求表达式.docx_第9页
第9页 / 共29页
数据结构课程设计用栈求表达式.docx_第10页
第10页 / 共29页
数据结构课程设计用栈求表达式.docx_第11页
第11页 / 共29页
数据结构课程设计用栈求表达式.docx_第12页
第12页 / 共29页
数据结构课程设计用栈求表达式.docx_第13页
第13页 / 共29页
数据结构课程设计用栈求表达式.docx_第14页
第14页 / 共29页
数据结构课程设计用栈求表达式.docx_第15页
第15页 / 共29页
数据结构课程设计用栈求表达式.docx_第16页
第16页 / 共29页
数据结构课程设计用栈求表达式.docx_第17页
第17页 / 共29页
数据结构课程设计用栈求表达式.docx_第18页
第18页 / 共29页
数据结构课程设计用栈求表达式.docx_第19页
第19页 / 共29页
数据结构课程设计用栈求表达式.docx_第20页
第20页 / 共29页
亲,该文档总共29页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

数据结构课程设计用栈求表达式.docx

《数据结构课程设计用栈求表达式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计用栈求表达式.docx(29页珍藏版)》请在冰点文库上搜索。

数据结构课程设计用栈求表达式.docx

数据结构课程设计用栈求表达式

课程设计报告

学院、系:

吉林大学珠海学院计算机科学与技术系

专业:

网络工程

班级:

十三班

课程设计科目

数据结构

学生姓名:

林艾鑫

指导教师:

余江

完成时间:

2010年10月-12月

 

题目十三、利用栈求表达式地值

一、设计任务与目标

编写程序实现表达式求值,即验证某算术表达式地正确性,若正确,则计算该算术表达式地值.

主要功能描述如下:

1、从键盘上输入表达式,以“=”号结束表达式.

2、分析该表达式是否合法:

(1)是数字,则判断该数字地合法性.若合法,则压入数据到堆栈中.

(2)是规定地运算符,则根据规则进行处理.在处理过程中,将计算该表达式地值.

(3)若是其它字符,则返回错误信息.

3、若上述处理过程中没有发现错误,则认为该表达式合法,并打印处理结果.

附加功能:

1.规定表达式地合法性

2.小数计算

3.计算记录地保存与查看

4.

(1)规定表达式地合法性,括号配对,不能出现“6++3”、“6+-3”等符号重叠地情况.

(2)表达式开头只能是数字或“(”,表达式中只能有一个“=”.

 

程序中应主要包含下面几个功能函数:

voidinitstack():

初始化堆栈

intmake_str():

语法检查并计算

intpush_num(doublenum):

将操作数压入堆栈

charprocede(chartop,charcode):

处理操作码

intchange_opnd(intoperate):

将字符型操作码转换成优先级

intchange_opnd(charcode):

将操作码压入堆栈

charpop_opnd(opnd*op):

将操作码弹出堆栈

intcaculate(intcur_opnd):

简单计算+,-,*,/

doublepop_num(num*nu):

弹出操作数

二、方案设计与论证

1.定义一个expression全局表达式结构体expr[1000]存放计算过地表达式(expstr[MAXSIZE])和计算结果(result)、一个计量器(i)、一个表达式字符串、一个操作码栈和一个操作数栈;

2.把表达式字符串从头到尾逐一扫描,将输入地表达式进行语法检查;

3.第一个字符只能是数字或“(”,最重一个字符只能是“=”;

4.表达式括号必须配对,中间不能出现“=”;

5.在“(”前面只能是“+、-、*、/、(”,在“+、-、*、/、=、)”前面只能是数字或“)”;

6.把表达式字符串从头到尾逐一扫描,直到表达式扫描完毕,操作码栈为空;

7.把字符根据运算优先级别选择操作;

8.把表达式中地数值部分字符串转成数值压入操作数栈;

9.是“(”直接压入到操作码栈,级别比操作码栈顶元素高地,把运算符压入操作码栈;

10.级别比操作码栈低地,弹出操作码栈地栈顶元素和操作数栈地两个栈顶元素,进行运算后再压入操作数栈;

11.是“)”,若操作码栈顶是“(”,把弹出操作码栈顶元素,否则“)”视为级别最低地元素,重复7;

12.最后计算出结果并将其存放在expr[i],计量器加1;

13.重复计算后,将结果保存在文件里,并统计计算次数;

14.查看多次计算结果,以表形式输出;

15.查看本次计算记录,以表形式输出;

16.清除计算记录,重新计算.

三、算法说明

(一)程序总共有如下函数:

主要函数:

voidstart(opnd*op,num*nu)//程序主菜单

voidstart2(opnd*op,num*nu)//第二层计算选择,子菜单

voidload()//显示所有计算记录

voidsave()//保存计算结果

voidcheck()//显示本次计算结果

voidresult(opnd*op,num*nu)//计算结果

doublecaculate(opnd*op,num*nu)//简单计算+,-,*,/

表达式处理函数:

intmake_str()//语法检查

doublechange_num(charstr[])//数字字符串转成double型数字

charprocede(chartop,charcode)//处理操作码,判断栈地操作

intchange_opnd(charcode)//字符型操作码转换优先级,非表达式字符返回-2

栈操作函数:

doubleget_num(num*nu)//查看操作数栈栈顶

doublepop_num(num*nu)//操作数栈出栈

intpush_num(num*nu,doubleda)//压入操作数栈

intempty_num(num*nu)//判空

voidinitstack(num*nu)

charget_opnd(opnd*op)//查看栈顶

charpop_opnd(opnd*op)//出栈

intpush_opnd(opnd*op,charco)//压栈

intempty_opnd(opnd*op)//判空

voidinitstack(opnd*op)//初始化栈

(二)函数间地调用关系:

●main():

主函数→start()。

↗load()→start()。

●start()程序模式函数→清空文件→exit()。

↘make_str()→result(op,nu)→start2()→start()。

↗load→start()。

●start2()子菜单→save()→start2()。

↘check()→start2()。

●result(op,nu)计算结果→initstack(op)→initstack(nu)→push_opnd(op,'=')→

↗push_num(nu,change_num(str2))。

→change_opnd(*ps)↗push_opnd(op,*ps);

↘procede(get_opnd(op),*ps)→pop_opnd(op)。

↘push_num(nu,caculate(op,nu))

●caculate(op,nu)→b=pop_num(nu)→a=pop_num(nu)→pop_opnd(op)

✓main()函数:

调用了一个函数start(),start()判断执行查看所有计算记录函数load(),或是清空以往地所有计算记录,或是退出程序,或是检查输入表达式语法make_str()并计算表达式result(op,nu)地操作.

✓result(op,nu)函数:

是计算表达式,调用了初始化栈函数和字符级别判断change_opnd(*ps),若是数字,则调用转化数字change_num(str2)然后压入操作数栈,若是运算符,刚调用判断操作procede(get_opnd(op),*ps),若是“<”,则压入操作码栈push_opnd(op,*ps),若是“=”,则弹出操作码栈顶pop_opnd(op),若是“>”,则弹出操作码栈地栈顶元素和操作数栈地两个栈顶元素,进行运算caculate(op,nu)后再压入操作数栈,计算完毕后按start()顺序运行.

✓start2()函数:

在计算结果后调用跟随地选择菜单,进行查看结果check()、保存结果save()、查看计算记录load()、回到主菜单地操作.

 

(三)流程图:

四、全部源程序清单

#include

#include

#include

#include

#defineMAXSIZE100

#defineN1000

inti=0。

//表达式数

structexpression//表达式结构

{

longdoubleresult。

charexpstr[MAXSIZE]。

}expr[N]。

//表达式地一个整体容器s

typedefstruct//操作码栈定义

{

charcode[MAXSIZE]。

inttop。

}opnd。

typedefstruct//操作数栈定义

{

doubledate[MAXSIZE]。

inttop。

}num。

//《——opnd栈操作——》:

voidinitstack(opnd*op)//初始化栈

{

op->top=-1。

}

intempty_opnd(opnd*op)//判空

{

if(op->top==-1)

return0。

elsereturn1。

}

intpush_opnd(opnd*op,charco)//压栈

{

if(op->top==MAXSIZE-1)

{

printf("The\"opnd\"stackisfull.")。

return0。

}

op->top++。

op->code[op->top]=co。

return1。

}

charpop_opnd(opnd*op)//出栈

{

chara='\0'。

if(op->top==-1)

{

printf("error:

The\"opnd\"stackisempty.")。

returna。

}

a=op->code[op->top]。

op->top--。

returna。

}

charget_opnd(opnd*op)//查看栈顶

{

chara='\0'。

if(op->top==-1)

{

printf("error:

The\"opnd\"stackisempty.")。

returna。

}

else

returnop->code[op->top]。

}

//《——num栈操作——》:

voidinitstack(num*nu)

{

nu->top=-1。

}

intempty_num(num*nu)//判空

{

if(nu->top==-1)

return0。

elsereturn1。

}

intpush_num(num*nu,doubleda)//压栈

{

if(nu->top==MAXSIZE-1)

{

printf("error:

The\"date\"stackisfull.")。

return0。

}

nu->top++。

nu->date[nu->top]=da。

return1。

}

doublepop_num(num*nu)//出栈

{

doublea='\0'。

if(nu->top==-1)

{

printf("error:

The\"date\"stackisempty.")。

returna。

}

a=nu->date[nu->top]。

nu->top--。

returna。

}

doubleget_num(num*nu)//查看栈顶

{

if(nu->top!

=-1)

returnnu->date[nu->top]。

}

//《——结束栈定义操作——》

//《——函数操作——》:

intchange_opnd(charcode)//将字符型操作码转换成优先级,非表达式字符反回-2

{

switch(code)

{

case'=':

return1。

break。

case')':

return2。

break。

case'+':

return3。

break。

case'-':

return3。

break。

case'*':

return4。

break。

case'/':

return4。

break。

case'(':

return0。

break。

//操作码级别>=0。

case'1':

case'2':

case'3':

case'4':

case'5':

case'6':

case'7':

case'8':

case'9':

case'0':

case'.':

return-1。

//操作数级别=-1;

default:

return-2。

//其它符号级别=-2

}

}

charprocede(chartop,charcode)//处理操作码,判断栈地操作

{

if(change_opnd(code)==0)//“(”入栈

return('<')。

else

if(change_opnd(code)==2&&change_opnd(top)==0)//“(”和“)”同时出现,“(”出栈,“)”不入栈

return('=')。

else

if(change_opnd(code)<=change_opnd(top))//弹出两个数字和一个符号进行计算

return('>')。

else

return('<')。

//入栈

}

doublechange_num(charstr[])//数字字符串转成double型数字

{

char*s=str。

intp=1,q=0。

//p=小数点前位数,q=小数点后位数

chard[]=".",z[]="0"。

doubleda=0。

if(strstr(str,d)==0)//判断是否有小数点

p=strlen(str)。

else

if(strstr(str,d)==str)//没有输入小数点前地数,如“.032”

{

p=1。

q=strlen(str)-1。

strcpy(str,strcat(z,str))。

}

else

{

p=strstr(str,d)-str。

q=strlen(str)-p-1。

}

for(inti=0。

i

i++)//小数点前地各位数乘以各自地阶数,然后叠加:

123=1*100+2*10+3*1

da=da+((int)str[i]-48)*pow(10,p-i-1)。

for(intj=0。

j

j++)//小数点后地各位数乘以各自地阶数,然后叠加:

0.123=1*0.1+2*0.01+3*0.001

da=da+((int)str[strlen(str)-1-j]-48)*pow(0.1,q-j)。

returnda。

}

intmake_str()//语法检查

{

char*p,*p1。

intn=0。

printf("\n请输入表达式,以“=”结尾:

")。

gets(expr[i].expstr)。

p=expr[i].expstr。

p1=p。

while

(1)

{

if(*p=='\0')

if(*(p-1)=='=')//语法检查结束

break。

else

{//没有以"="结尾

printf("\n表达式以\"=\"结尾.请重新输入:

")。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

if(change_opnd(*p)==2)//一个")",n-1

n--。

if(change_opnd(*p)==0)//一个"(",n+1

n++。

if(*p1==*p)//第一个字符地判断,只能以“数字”或“(”开头,不能有非法字符

if(change_opnd(*p)>0)

{

printf("\n表达式只能以“数字”或“(”开头.请重新输入:

")。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

else

if(change_opnd(*p)==-2)

{

printf("\n表达式\"%c\"为非法字符.请重新输入:

",*p)。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

else

{//合法刚跳到下一个字符

p=p+1。

continue。

}

if(change_opnd(*p)==-2)//非法字符判断

{

printf("\n表达式\"%c\"为非法字符.请重新输入:

",*p)。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

if(change_opnd(*p)==0)//"("前一个字符只能是"+、-、*、/、("

{

if(change_opnd(*(p-1))<3&&change_opnd(*(p-1))>4)

if(change_opnd(*(p-1))!

=0)

{

printf("\n表达式\"%c\"或\"%c\"不符合语法.请重新输入:

",*(p-1),*p)。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

}

if(change_opnd(*p)>0)//"+、-、*、/、=、)"前一个字符只能是数字和")"

if(change_opnd(*(p-1))!

=-1)

if(change_opnd(*(p-1))!

=2)

{

printf("\n表达式\"%c\"或\"%c\"不符合语法.请重新输入:

",*(p-1),*p)。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

if(change_opnd(*p)==1)//判断表达式中是否有"="重复出现,最后括号是否配对

{

if(*(p+1)!

='\0')

{

printf("\n表达式中\"=\",只能出现在表达式结束处.请重新输入:

")。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

if(n!

=0)

{

printf("\n表达式括号不配.请重新输入:

")。

gets(expr[i].expstr)。

p=expr[i].expstr。

n=0。

continue。

}

}

p=p+1。

}

return1。

}

 

doublecaculate(opnd*op,num*nu)//简单计算+,-,*,/

{

doubleb=pop_num(nu),a=pop_num(nu)。

switch(pop_opnd(op))

{

case'+':

return(a+b)。

break。

case'-':

return(a-b)。

break。

case'*':

return(a*b)。

break。

case'/':

return(a/b)。

break。

}

}

voidresult(opnd*op,num*nu)//计算结果

{

charstr2[MAXSIZE]="",str3[2]="0"。

char*ps=expr[i].expstr。

initstack(op)。

//初始化栈

initstack(nu)。

push_opnd(op,'=')。

while(!

((*ps=='=')&&(get_opnd(op)=='=')))//检查是表达式和操作码是否到尾

if(change_opnd(*ps)==-1)//操作数处理

{

while(change_opnd(*ps)==-1)

{

strncpy(str3,ps,1)。

//数字字符一个个取出放在str2

strcat(str2,str3)。

ps++。

}

push_num(nu,change_num(str2))。

strcpy(str2,"")。

}

else//操作码处理

{

switch(procede(get_opnd(op),*ps))

{

case'<':

push_opnd(op,*ps)。

break。

case'=':

pop_opnd(op)。

break。

case'>':

push_num(nu,caculate(op,nu))。

continue。

break。

}

if(*ps==')'&&get_opnd(op)=='=')

{

ps++。

continue。

}

if(*ps=='='||get_opnd(op)=='=')

continue。

//表达式和操作码有一个到尾,则跳出继续循环

ps++。

}

expr[i].result=get_num(nu)。

printf("\n\t表达式:

%s\t计算结果:

%lf\n",expr[i].expstr,expr[i].result)。

printf("\t----------------------------------------------------------------\n")。

i++。

//表达式个数加1;

}

voidcheck()//显示计算结果

{

for(intn=0。

n

n++)

{

printf("\n")。

printf("\t%d--------------------------------------------------------------\n",n+1)。

printf("\t表达式:

%s",expr[n].expstr)。

printf("\t计算结果:

%.2lf\n",expr[n].result)。

if(expr[n].expstr[0]=='#')break。

//只显示当次计算地记录

}

printf("\t---------

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

当前位置:首页 > 求职职场 > 社交礼仪

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2