表达式求值课程设计数据结构C语言版Word文档格式.docx
- 文档编号:17014312
- 上传时间:2022-11-27
- 格式:DOCX
- 页数:23
- 大小:375.79KB
表达式求值课程设计数据结构C语言版Word文档格式.docx
《表达式求值课程设计数据结构C语言版Word文档格式.docx》由会员分享,可在线阅读,更多相关《表达式求值课程设计数据结构C语言版Word文档格式.docx(23页珍藏版)》请在冰豆网上搜索。
5.2求值操作流程3
六.个性功能介绍4
七.部分问题及解决方案5
7.1不能进行带有小数点的数的运算5
7.2在输错后,跳回主界面直接提示指令输入错误,重输6
八.课程设计小结7
九.附录一:
部分测试数据7
十.附录二:
源代码7
一、题目:
二、课程设计任务:
要求能输入一个带“()”的任意多位实数的表达式。
要求:
1、有合理的提示;
2、有非法数据的判断;
3、能够进行多次计算。
测试数据及测试结果请在上交的资料中写明;
三、问题分析:
任何一个表达式都是由操作符,运算符组成的。
我们分别用顺序栈来寄存表达式的操作数和运算符。
栈是限定于紧仅在表尾进行插入或删除操作的线性表。
顺序栈的存储结构是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素。
为了实现算符优先算法。
可以使用两个栈。
一个称为Schar,用以寄存运算符,另一个称做Sfloat,用以寄存操作数或运算结果。
1.首先置操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素;
2.依次读入表达式,若是操作符即进Sfloat栈,若是运算符则和Schar栈的栈顶运算符比较优先权后作相应的操作,直至整个表达式求值完毕(即Schar栈的栈顶元素和当前读入的字符均为”#”)。
四、结构分析:
1.用于存储操作数和运算结果(Sfloat):
ADTs_float{
数据元素:
此链栈中的所有元素类型为字符型的数字字符
数据关系:
栈中数据元素之间是线性关系。
基本操作:
(1)Init(Sfloat*S);
初始化数字栈
(2)Push(Sfloat*S,floate)
进栈
(3)Pop(Sfloat*S,float*x)
出栈
(4)GetTop(Sfloat*S,float*x)
取栈顶
(5)voidClearStack(Sfloat*S)
清空栈
}ADTs_float
2.用于存储运算符(Schar):
ADTs_char{
数据对象D:
元素类型为字符型的符号字符
数据关系R:
基本操作:
(1)Init(Schar*S)
初始化字符栈
(2)Push(Schar*S,charx)
进栈
(3)Pop(Schar*S,char*x)
出栈
(4)GetTop(Schar*S,char*x)
取栈顶
(5)ClearStack(Schar*S)
清空栈
}ADTs_char
3.系统中子程序及功能要求:
(1)boolIsFloat(charch)
判断输入的是否为数字
(2)boolIsChar(charch)
判断输入的是否为所需要的字符
(3)floatGetNumber(char*ch)
将字符型数字转化为浮点型
(4)floatOperation(floata,charsign,floatb)
+、-、*、/的基本运算
(5)intCmp(charx,charch)
比较字符的优先级
(6)voidMaster();
程序主功能函数
(7)voidError()
错误提示界面
(8)voidWelcome()
程序欢迎界面
(9)voidEnd()
结束选择界面
五、实现流程
1.程序主流程图
2.求值操作流程
(下例为3*(7-2)的操作流程)
步骤
Schar栈
Sfloat栈
输入表达式
主要操作
1
#
3*(7-2)#
Push(Sfloat,’3’)
2
3
*(7-2)#
Push(Schar,’*’)
#*
(7-2)#
Push(Schar,’(’)
4
#*(
7-2)#
Push(Sfloat,’7’)
5
37
-2)#
Push(Schar,’-’)
6
#*(-
2)#
Push(Sfloat,’2’)
7
372
)#
Operation(‘7’,’-’,’2’)
8
35
Pop(Sfloat)
9
Operation(‘3’,’*’,5’)
15
Return(GetTop(Sfloat))
六、个性功能介绍
在本程序中,通过windows头文件的作用,实现了程序背景色的改变,不在是原本的黑白色,让人看得很新颖。
通过Sleep函数,让程序出错或跳转其它界面时,不是迅速跳过,而是先提示即将跳转,让使用者更方便地了解程序的基本执行过程。
七、实验过程中遇到的部分问题及解决方案
1.不能进行带有小数点的数的运算
①错误运行结果
②解决方案
③解决后运行结果
2.在输入错误后,跳回主界面时直接提示指令输入错误,重新输入。
①解决方案
导致这个的原因是错误后跳回主界面没有清除缓存,所以需要在错误提示函数中添一个fflush(stdin)来刷新当前内存。
②运行结果
八、课程设计小结
通过这次的课程设计,让我更加地了解到C语言和数据结构的魅力。
课程设计不仅要求对课本知识有较深刻的了解,同时要求程序设计者有较强的思维和动手能力,同时这也使我更加了解编程思想和编程技巧。
这次课程设计让我有一个深刻的体会,那就是细节决定成败,编程最需要的是严谨,如何的严谨都不过分,往往检查了半天发现错误发生在某个括号,分号,引号,或者数据类型上,还有函数或变量命名一般要遵循其默认命名规则。
就像我在写Master()函数时,起初将各种标识符名称设置的乱七八糟,导致我后面自己都对各种变量名的指向的作用都混淆了,后来还浪费了大量的时间进行优化命名,所以说细节很重要。
程序设计时,也不要怕遇到错误,在实际操作过程中犯的一些错误还会有意外的收获,感觉课程设计很有意思。
在具体操作中这学期所学的数据结构的理论知识得到巩固,达到课程设计的基本目的,也发现自己的不足之出,在以后的上机中应更加注意。
以后我们会继续努力,大胆创新,争取能编写出透射着自己思想的程序。
这次课程设计让我们充分认识到了自己的不足,认识到了动手能力的重要性。
我们会在以后的学习中更加努力锻炼自己,提高自己,让自己写出更好更完善的程序,为以后的编程打好基础!
附录一:
部分测试数据
组别
表达式
正确值
1.23+4.5*10
46.23
1.5*(1+9)-10/5
13
-(100-101)/5
0.20
1.23.5+6.5*12
错误
5+4*1.25)
附录二:
源代码
#include<
stdio.h>
stdlib.h>
windows.h>
#defineMAXSIZE20
////////////////////////////////建立字符栈
typedefstruct
{
chararr[MAXSIZE];
inttop;
}Schar;
voidInit(Schar*S)//初始化
S->
top=-1;
}
intPush(Schar*S,charx)//进栈
if(S->
top==MAXSIZE-1)
return0;
top++;
arr[S->
top]=x;
return1;
intPop(Schar*S,char*x)//出栈
top==-1)
else
{
*x=S->
top];
top--;
}
intGetTop(Schar*S,char*x)//取栈顶
charGetTop(ScharS)
charx;
GetTop(&
S,&
x);
returnx;
voidClearStack(Schar*S)//清空栈
top!
=-1)S->
////////////////////////////////建立数字栈
typedefstruct
floatarr[MAXSIZE];
}Sfloat;
voidInit(Sfloat*S)//初始化
intPush(Sfloat*S,floate)//进栈
top==MAXSIZE-1)
top]=e;
intPop(Sfloat*S,float*x)//出栈
*x=S->
intGetTop(Sfloat*S,float*x)//取栈顶
top==-1)
floatGetTop(SfloatS)
floatx;
voidClearStack(Sfloat*S)//清空栈
=-1)
S->
chara[7]={'
+'
'
-'
*'
/'
('
)'
#'
};
intpri[7][7]={//优先权集合
{1,1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,1,1},
{1,1,1,1,-1,1,1},
{-1,-1,-1,-1,-1,0,2},
{1,1,1,1,2,1,1},
{-1,-1,-1,-1,-1,2,0}};
boolIsFloat(charch)//判断数字
if((ch>
=48&
&
ch<
=57)||ch==46)
returntrue;
//输入数字或小数点返回真,否则为假
else
returnfalse;
boolIsChar(charch)//判断字符
if(ch=='
||ch=='
)
//输入指定字符返回真,否则为假
}
floatGetNumber(char*ch)//将字符型数字转化为浮点型
returnfloat(*ch)-'
0'
;
floatOperation(floata,charsign,floatb)//基本运算
switch(sign)
case'
:
return(a+b);
break;
return(a-b);
return(a*b);
default:
return(a/b);
intCmp(charx,charch)//比较优先级
inti,j,k;
for(i=0;
i<
7;
i++)
if(x==a[i])j=i;
if(ch==a[i])k=i;
returnpri[j][k];
Schars_char;
Sfloats_float;
voidMaster();
//定义Master()函数
voidError()//错误提示界面
printf("
输入错误,程序即将跳转至主界面\n"
);
Sleep(1000);
//延迟一秒
fflush(stdin);
//清除缓存
system("
cls"
//清屏
Master();
//调用主函数
voidWelcome()//欢迎界面
Init(&
s_char);
//初始化字符栈
s_float);
//初始化数字栈
Push(&
s_char,'
***********************************\n"
*欢迎进入表达式串求值系统*\n"
*1.进行输入*\n"
*0.退出系统*\n"
请输入你需要操作的选项:
"
intchoose;
scanf("
%d"
&
choose);
while(choose!
=1&
choose!
=0)
{fflush(stdin);
printf("
\n错误,重新输入指令:
scanf("
if(choose==0)
{printf("
感谢体验本系统,再见!
\n"
exit
(1);
voidMaster();
voidEnd()//结束选择界面
intchoose2;
是否再次进行表达式串求值(1-是,2-否):
choose2);
while(!
(choose2==1||choose2==2))
输入指令号错误,重输:
if(choose2==1)
即将跳转至功能主界面\n"
Sleep(1000);
system("
Master();
感谢谢体验本系统,再见!
return;
voidMaster()//主函数
Welcome();
//调用欢迎界面函数
请输入一个表达式串(以#结束)\n"
charch;
//标记小数点、翻多少倍
intnum_point=0,num_times=1;
//定义各种标记符
intfu_sign=0,shu_sign=0,char_sign=0,kh_sign=0,m=0;
floatn=0,value,a,b;
charop;
ch=getchar();
if(!
IsFloat(ch))//输入的第一个字符不是数字
if(ch=='
)
kh_sign=1;
//标记kh_sign
elseif(ch=='
{
fu_sign=1;
//标记fu_sign
ch=getchar();
}
else
Error();
while(ch!
='
||GetTop(s_char)!
if(!
IsChar(ch)&
!
IsFloat(ch))
//当输入的不是目标字符或数字,错误提示
if(IsFloat(ch))//输入的是数字
if(shu_sign==0)
if(ch==46)//还没输入数字就输入小数点
Error();
if(num_point==1)
num_times*=10;
//翻10倍
if(!
(ch==46))
{
n=n*10+GetNumber(&
ch);
//转化成float型
shu_sign=1;
//记录输入数字
char_sign=0;
//记录字符
}
if(ch==46)
num_point++;
//小数点标识加1
if(num_point>
1)//若一个数有两个小数点
Error();
if(IsChar(ch))//输入的为指定的字符
if(ch=='
kh_sign=1;
//kh_sign标记为1
if(fu_sign==1)//最前面有负号
if(shu_sign==0)//没记录到有数字
{
if(kh_sign==1)//记录到输入了"
("
{
Push(&
s_char,ch);
//将"
存入字符栈中
kh_sign=0;
//重新将标记kh_sign置0
m=2;
//记录负的左括号
ch=getchar();
continue;
}
else
Error();
}
else//记录到前面有数字
n=-n;
//乘上负号
fu_sign=0;
//将负号标记记置0
if(m==2)
n=-n;
m--;
}
if(shu_sign==1)
if(num_times==1)
if(num_point)
n=n/num_times;
Push(&
s_float,n);
//将数字存入数字栈中
n=0;
//初始化为0
shu_sign=0;
//当前n值已被存进栈中
num_point=0;
//小数点标识符置零
num_times=1;
//n进位初值
if(char_sign==1)
if(GetTop(s_char)=='
ch=='
{
fu_sign=1;
//负号标识fu_sign置1
ch=getchar();
}
elseif(ch=='
kh_sign=1;
//记录左括号
//调用错误提示函数
if(char_sign==0||kh_sign==1)
switch(Cmp(GetTop(s_char),ch))//比较优先级
case-1:
//当优先级小
//进栈
char_sign=1;
break;
case1:
//当优先级大
Pop(&
s_char,&
op);
s_float,&
b);
a);
if(op=='
b==0)
Error();
value=Operation(a,op,b);
if(m==1)//当负号标识符为1
{
value=-value;
//取相反值
m=0;
}
s_float,value);
case0:
//当优先级相同
case2:
//错误
value=GetTop(s_float);
//得到最终结果
if(value==int(value))//得到整数就输出整数部分
计算结果为:
%.f\n"
value);
else//得到小数则保留两位
%.2f\n"
End();
//调用退出函数界面
voidmain()
color3f"
//调用主函数
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 表达式 求值 课程设计 数据结构 语言版