利用栈求表达式的值可供小学生作业并能给出分数数据结构课程设计说明书格式.docx
《利用栈求表达式的值可供小学生作业并能给出分数数据结构课程设计说明书格式.docx》由会员分享,可在线阅读,更多相关《利用栈求表达式的值可供小学生作业并能给出分数数据结构课程设计说明书格式.docx(20页珍藏版)》请在冰豆网上搜索。
利用栈求表达式的值可供小学生作业并能给出分数数据结构课程设计说明书格式
中北大学
数据结构
课程设计说明书
学生:
敏杰
学号:
1021011545
学院:
软件学院
专业:
软件开发与测试
题目:
利用栈求表达式的值,可供小学生作业,并能给出分数
指导教师
何志英
2011年12月20日
1.设计任务概述(包括系统总体框图及功能描述)
此课题是研究表达式求值的问题,以帮助小学生完成测试。
为了达到这个功能,实际我们要做的就是出题,和计算分数给出评价的工作。
整体设计都是以这个要求为轴心进行的。
为了直观和方便,现画出软件整体设计模块图。
整体设计模块图可以清晰的看出软件的几大模块。
整个系统的操作流程图可以看出操作的整体流程,如下图
2.本设计所采用的数据结构(如:
链表、栈、树、图等)
根据以上功能说明,设计运算信息,堆栈的存储结构,设计程序
完成功能;
3.功能模块详细设计
在此说明每个部分的算法设计说明(可以是描述算法的流程图),每个程序中使用的存储结构设计说明(如果指定存储结构请写出该存储结构的定义)。
3.1详细设计思想
学生要进行测试,首先要有试题。
那么我们就要先建立试题库。
这个试题库的试题是我们在程序运行过程中手动输入,存放在一个shujuku.txt的文件中。
首先在主函数中调用创建试题库函数,将试题存入到试题库文件shitiku.txt中,然后将该调用从主函数中删除。
创建试题库函数:
创建指向xuanti类型的指针,利用循环将输入的测试题该指针的xuanti单元中,最后将该指针中的测试题写入试题库文件shitiku.txt中。
3.2核心代码
(正文宋体小四号字,1.5倍行距)
#include
#include
#include
#include
#include
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#defineERROR0
#defineOK1
//定义表达式
typedefstructshiti
{
chara[20];
longresult;
}xuanti;
typedefstructSqStack1
{//建立数字栈
int*base;
int*top;
intstacksize;
}SqStack1;
typedefstructSqStack2
{//建立运算符栈
char*base;
char*top;
intstacksize;
}SqStack2;
voidWriteToFile(xuanti*pstu,intnum);
voidReadFromFile(xuanti*pstu,intnum);
voidpage_title(char*menu_item)
{//建立菜单
printf(">>>数学习题库<<<\n\n-%s-\n\n",menu_item);
}
voidreturn_confirm()
{
printf("\n按任意键返回……\n");
getch();
}
voidIntInitStack(SqStack1*S1)
{
S1->base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));
if(!
S1->base)
exit(ERROR);
S1->top=S1->base;
S1->stacksize=STACK_INIT_SIZE;
}//IntInitStack
voidCharInitStack(SqStack2*S2)
{
S2->base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
if(!
S2->base)
exit(ERROR);
S2->top=S2->base;
S2->stacksize=STACK_INIT_SIZE;
}//CharInitStack
longIntGetTop(SqStack1*S1)
{//取栈顶元素
longe1;
if((*S1).top==(*S1).base)
return0;
e1=*((*S1).top-1);
returne1;
}//IntGetTop
charCharGetTop(SqStack2*S2)
{//取栈顶元素
chare2;
if((*S2).top==(*S2).base)return0;
e2=*((*S2).top-1);
returne2;
}//IntGetTop
intIntPush(SqStack1*S1,inte1)
{//入栈
*(*S1).top++=e1;
returnOK;
}//IntPush
intCharPush(SqStack2*S2,chare2)
{//入栈
*(*S2).top++=e2;
returnOK;
}//CharPush
intIntPop(SqStack1*S1)
{//出栈
inte1;
if((*S1).top==(*S1).base)
return0;
e1=*--(*S1).top;
returne1;
}//IntPop
intCharPop(SqStack2*S2)
{//出栈
chare2;
if((*S2).top==(*S2).base)return0;
e2=*--(*S2).top;
returne2;
}//CharPop
charPrecede(chara,charb)
{
inti,j;
charTable[8][8]={'','+','-','*','/','(',')','#',
'+','>','>','<','<','<','>','>',
'-','>','>','<','<','<','>','>',
'*','>','>','>','>','<','>','>',
'/','>','>','>','>','<','>','>',
'(','<','<','<','<','<','=','',
')','>','>','>','>','','>','>',
'#','<','<','<','<','<','','=',
};//优先级表格
for(i=0;i<8;i++)
if(Table[0][i]==a)//纵坐标寻找
break;
for(j=0;j<8;j++)//横坐标寻找
if(Table[j][0]==b)
break;
returnTable[j][i];
}//Precede
intOperate(inta,chartheta,intb)
{//计算表达式值:
主要是将大的表达式转化成小的表达式进行逐步求值
intc;
if(theta=='+')c=a+b;
elseif(theta=='-')c=a-b;
elseif(theta=='*')c=a*b;
elsec=a/b;
returnc;
}//Operate
intIsOptr(charch)
{
charptr[10]={'+','-','*','/','(',')','#'};
for(inti=0;i<7;i++)
{
if(ch==ptr[i])
returntrue;
}
returnfalse;
}
longresult(char*a,SqStack1*OPND,SqStack2*OPTR)
{//求值
chartheta;
intb,d,k=0,i=0,j=0,num2=0;
IntInitStack(OPND);
CharInitStack(OPTR);
CharPush(OPTR,'#');
while(a[i]!
='=')
{
if(!
IsOptr(a[i]))
{
k++;
if(k<=j)
{
num2=(int(a[i])-48);
i++;
}
if(k>j)
{
num2=num2*10+(int(a[i])-48);
k=j=0;
i++;
}
if(!
IsOptr(a[i]))
k++;
if(k==j)
IntPush(OPND,num2);
}
elseif(IsOptr(a[i]))
{
switch(Precede(a[i],CharGetTop(OPTR)))
{
case'<':
CharPush(OPTR,a[i++]);
if(a[i]!
='('&&a[i]!
=')')
j++;
break;
case'=':
CharPop(OPTR);i++;break;
case'>':
theta=CharPop(OPTR);
d=IntPop(OPND);
b=IntPop(OPND);
IntPush(OPND,Operate(b,theta,d));
break;
}//switch
}//elseif
}//while
printf("表达式的正确结果为:
");
printf("%d\n",IntGetTop(OPND));
return(IntGetTop(OPND));
}//reslut
voidBuilt_shitiKu()
{
inti,num;
xuanti*pstu;
printf("输入试题数目:
\n");
scanf("%d",&num);
fflush(stdin);
pstu=(xuanti*)malloc(num*sizeof(xuanti));//动态分配存
if(pstu==NULL)
{
printf("没有足够的存空间!
\n");
return;
}
for(i=0;i{//输入试题
printf("第%d道试题:
",i+1);
gets(pstu[i].a);
fflush(stdin);
printf("\n");
}
WriteToFile(pstu,num);//将pstu所指向的学生信息写入文件中
memset(pstu,0,num*sizeof(xuanti));//将pstu所指向的存块清0
ReadFromFile(pstu,num);//从文件中读取学生信息到pstu所指向的存块中
printf("试题列表:
\n");
for(i=0;i{//输入试题
printf("第%d道试题:
",i+1);
printf("%s",pstu[i].a);
printf("\n");
}
free(pstu);//释放动态分配的存
}
voidWriteToFile(xuanti*pstu,intnum)
{//将pstu所指向的试题息写入文件shitiku.txt中
FILE*fp;
fp=fopen("shitiku.txt","at");
if(fp==NULL)
{
printf("不能创建shitiku.txt\n");
free(pstu);
exit(0);
}
fwrite(pstu,sizeof(xuanti),num,fp);
fclose(fp);
}
voidReadFromFile(xuanti*pstu,intnum)
{//从试题库中提取试题
FILE*fp;
fp=fopen("shitiku.txt","rt");
if(fp==NULL)
{
printf("不能打开shitiku.txt\n");
free(pstu);
exit(0);
}
fread(pstu,sizeof(xuanti),num,fp);
fclose(fp);
}
//******************************************
voidRecMark(int*m,intnum)
{//把得分记录到markrec.txt中
FILE*mp;
mp=fopen("markrec.txt","at");
if(mp==NULL)
{
printf("不能创建markrec.txt\n");
free(m);
exit(0);
}
fwrite(m,sizeof(int),num,mp);
fclose(mp);
}//Recmark
voidLookMark(int*m,intnum)
{//查看得分记录
FILE*mp;
mp=fopen("markrec.txt","rt");
if(mp==NULL)
{
printf("不能打开markrec.txt\n");
free(m);
exit(0);
}
fread(m,sizeof(int),num,mp);
fclose(mp);
}
//*************************************
voidRecN(int*m,intnum)
{//把m的值记录到n_rec.txt中
FILE*mp;
mp=fopen("n_rec.txt","wt");
if(mp==NULL)
{
printf("不能创建n_rec.txt\n");
free(m);
exit(0);
}
fwrite(m,sizeof(int),num,mp);
fclose(mp);
}//Recmark
voidLookN(int*m,intnum)
{//查看m的值
FILE*mp;
mp=fopen("n_rec.txt","rt");
if(mp==NULL)
{
printf("不能打开n_rec.txt\n");
free(m);
exit(0);
}
fread(m,sizeof(int),num,mp);
fclose(mp);
}
//*************************************
intexcersice_begin()
{
inti,j,temp,KEY[20];
intmark,count=0;
int*Mark;
charg;
SqStack1s1,*OPND;
SqStack2s2,*OPTR;
xuanti*XT;
OPND=&s1;
OPTR=&s2;
Mark=(int*)malloc(20*sizeof(int));
XT=(xuanti*)malloc(20*sizeof(xuanti));
ReadFromFile(XT,20);
do
{
mark=0;
srand((unsigned)time(NULL));
KEY[0]=rand()%20;
for(i=1;i<20;i++)
{
while
(1)
{
temp=rand()%20;
for(j=0;j
{
if(KEY[j]==temp)
break;
}
if(j==i)
{
KEY[i]=temp;
break;
}
}
}
system("cls");
printf("随机的10个练习题:
\n");
for(i=0;i<10;i++)
{
printf("第%d个练习题:
",i+1);
printf("%s\n",XT[KEY[i]].a);
printf("请输入计算结果:
");
scanf("%ld",&XT[KEY[i]].result);
fflush(stdin);
if(XT[KEY[i]].result==result(XT[KEY[i]].a,OPND,OPTR))
{
mark+=10;
printf("答案正确!
");
printf("\n\n");
}
else
{
printf("答案错误!
");
printf("\n\n");
}
}
printf("****得分情况****\n");
printf("最后的得分为:
%d\n",mark);
if(mark>=90)
printf("VeryGood!
\n");
elseif(mark>=60)
printf("成绩不错。
\n");
elseprintf("很遗憾成绩不及格!
\n");
printf("\n");
RecMark(Mark,count);
Mark[count]=mark;
count++;//记录次数递增
printf("是否继续做练习?
('y'—是,'n'—否):
");
g=getchar();
fflush(stdin);
printf("\n");
if(count>=20)//超过最大记录次数清0
count=0;
}
while(g=='y');
RecMark(Mark,count);
returncount;
return_confirm();
}
voidLook_Mark(intcount)
{//printf("是否查看历史得分?
('y'—是,'n'—否):
");
int*Mark;
inti;
Mark=(int*)malloc(20*sizeof(int));
system("cls");
printf("****查询历史得分情况****\n");
LookMark(Mark,count);
for(i=0;iprintf("****第%d次得%d分****\n",i+1,Mark[i]);
if(i>1)
{
if(Mark[i-1]>60||Mark[i-2]>60)
{
if(Mark[i-1]>Mark[i-2])
printf("有进步,还要加油哦。
\n");
elseif(Mark[i-1]==Mark[i-2])printf("成绩还可以,但没有进步,还要多多努力呀!
\n");
elseprintf("成绩有点下降,要多多练习,不要气馁!
!
\n");
}
elseprintf("成绩很不好!
要更加努力学习!
\n");
}
else
{
if(Mark[0]>=90)
printf("VeryGood!
\n");
elseif(Mark[0]>=60)
printf("成绩不错。
\n");
elseprintf("很遗憾成绩不及格!
\n");
}
return_confirm();
}
voidmain()
{
intm=0;
int*RN;
charch;
RN=(int*)malloc(1*sizeof(int));
RN[0]=0;
printf("***如果是第一次运行***\n");
printf("**请先建立n_rec.txt**\n");
printf("*****否则会出错!
*****\n");
printf("('y'--创建**'n'--不建)\n");
ch=getchar();
if(ch=='y')
RecN(RN,1);
LookN(RN,1);
RN[0]+=m;
fflush(stdin);
printf("是否向试题库中添加试题:
");
printf("('y'--是,'n'--否)?
\n");
ch=getchar();
if(ch=='y')
Built_shitiKu();
menu:
page_title("操作选单");
printf("请用数字键选择操作\n\n");
printf("1开始练习\n");
printf("2查看得分记录\n");
printf("0退出\n");
printf("******************\n");
RN[0]+=m;
m=0;
switch(getch())
{
case'1':
m=excersice_begin();
break;
case'2':
Look_Mark(RN[0]);
break;
case'0':
{
RecN(RN,1);
exit(0);
}
}
system("cls");
gotomenu;
}
3.3程序运行结果(拷屏)
4.课程设计心得、存在问题及解决方法
连续两个星期的课程设计做完了,感觉自己的能力得到了大大的提高。
刚开始看见题目的时候,很不以为然,觉得这么简单。
但当自己开始着手做的时候才发现并不是那么回事。
一个看似简单的问题,有时候却牵扯甚多。
经过两个星期的上机实践学习,使我对C语言有了更进一步的认识和了解,要想学好它要重在实践,要通过不断的上机操作才能更好地学习它,通过实践,我也发现我的好多不足之处,对C语言学习平时只是马马虎虎的过去了,真正自己去解决实际问题的时候才会发现自己学的多么糟糕,通过课程设计对自己的编程能力也有所提高;再有对C语言的文件操作这一块,真的是难了我好久。
还有对函数调用的正确使用不够熟悉,还有对C语言中经常出现的错误也不了解,通过实践,使我在这几个方面的认识有所提高。
通过实践的学习,我认到学好计算机要重视实践操作,不仅仅是学习C语言,还是其它的语言,以及其它的计算机方面的知识都要重在实践,所以后在学习过程中,我会更加注重实践操作能力的培养,无论学习什么,亲自动手去做了才能得到最深刻的体会。