级数据结构课程设计任务书 及报告Word下载.docx
《级数据结构课程设计任务书 及报告Word下载.docx》由会员分享,可在线阅读,更多相关《级数据结构课程设计任务书 及报告Word下载.docx(18页珍藏版)》请在冰豆网上搜索。
![级数据结构课程设计任务书 及报告Word下载.docx](https://file1.bdocx.com/fileroot1/2023-1/22/1f76d241-1714-465a-a829-e60d206f0bd5/1f76d241-1714-465a-a829-e60d206f0bd51.gif)
运算符
4.将中缀表达式转换为后缀表达式传入参数:
中缀表达式
5.比较运算符优先级大小传入参数:
两个运算符
【提交成果】
1.“《数据结构与算法设计》课程设计任务书”一份,打印装袋;
2.“《数据结构与算法设计》课程设计报告”一份,打印装袋;
3.上面两项内容的word文档,通过电子邮件交到指导教师。
起止时间
2013年6月3日至2013年6月14日
指导教师签名
2013年6月3日
系(教研室)主任签名
2013年6月3日
学生签名
2013年6月3日
数据结构与算法设计课程设计
1.程序设计说明书
【设计题目】中缀表达式的解析程序
【问题描述】
通常程序语言中的算术表达式由算术运算符、变量、常量及括号组成。
编写一个算法程序判断
中缀表达式的语法正确性,并通过将中缀表达式转换成后缀表达式求解表达式的值。
1.可通过键盘输入算术表达式的中缀表达式,并检查中缀表达式的正确性;
2.将中缀表达式转化为后缀表达式;
3.计算后缀表达式的值,并输出;
1.将中缀表达式转换为后缀表达式的算法思想:
Step1:
定义符号栈,用于存放表达式的运算符;
Step2:
定义成员方法,用于比较运算符优先级;
Step3:
定义列表,用于存放后缀表达式;
Step4:
依次遍历表达式:
若为运算符:
比较当前运算符优先级与栈顶运算符优先级
A.栈顶运算符优先级>
=当前运算符优先级
则把栈中运算符优先级>
=当前运算符优先级的运算符
加入后缀表达式中;
B.栈顶运算符优先级<
当前运算符优先级
(即当前运算符优先级为最大)
则直接压入栈;
若为左括号:
直接压入栈;
若为右括号:
直接把栈中左括号前面的运算符出栈,并加入后缀表达式中;
若为井字号:
表示遍历完中缀表达式
则把栈中的操作符全部出栈,并加入后缀表达式中
若为操作数:
加入后缀表达式
2.计算后缀表达式的值的算法:
Step1:
定义数栈,用于辅助后缀表达式的计算;
Step2:
定义成员方法,用于计算两个操作数的值;
Step3:
从左到右依次遍历后缀表达式:
A.若为操作数:
B.若为运算符:
从栈顶依次出栈两个操作数,
计算出结果,再压入栈
Step4:
遍历完后缀表达式:
栈顶元素出栈,即为后缀表达式的值;
例如:
【基本操作设计】
【模块及调用关系】
【逻辑结构设计】
该设计采用线性结构,内存中连续的存储空间
【存储结构设计】
顺序存储:
顺序栈“先进后出”
top
bottom
【用户手册】
用户从键盘输入中缀表达式,程序输出转换后的后缀表达式以及后缀表达式的结果
2.程序上机调试报告
【语法错误及其排除】
1.没有导入java.util.Scanner,输入错误;
2.循环体少右大括号,致使循环体错误;
3.有些语句少分号;
【算法错误及其排除】
1.在中缀表达式转化为后缀表达时,没有考虑两位数以及更高位数的存放,把每位数单独存
放,致使进行运算时,因为运算符是两位数的运算符,取数进行运算只可以取出两位个位的
数,不符合原表达式;
排除:
对于两位或更高位的数,循环遍历,将一个两位或更高位的数,作为一个整体数,
存放到一个字符串的数组,
2.在中缀表达式转化为后缀表达式时,将栈中优先级>
=当前优先级的优先级加入到后缀表达式
中时,取栈顶元素,栈顶指针没有下移,导致输出后缀表达式错误
栈顶元素出栈,栈顶指针下移,然后再取栈顶元素
3.计算后缀表达式时,将取得第一个栈顶元素是操作数1,第二个栈顶元素为操作数2,导致
运算结果错误;
取得第一个栈顶元素是操作数2,第二个栈顶元素为操作数1
3.程序测试结果
【测试数据】
【输出结果】
图1
图2
图3
图4
图5
【程序性能评价】
本程序是利用数据结构——栈“先进后出”这一特点,实现将中缀表达式转换为后缀表达式
并进行计算的,无论是对于个位数还是对于两位或更高位的整数,可以快速的实现中缀转换为后缀
表达式并进行后缀表达式的加减乘除四则运算。
【性能改进方向】
如果可以再实现对小数的运算或实现求余、乘方等更高级的运算就会更好一些,同时也可以使用链式栈进行操作,会比较节省内存空间。
【收获及体会】
这次课程设计从选择设计的题目到做完这个设计,都是在不断的思考、探索当中进步,包括看到这个题目——后缀表达式的解析程序,一开始对后缀表达式的理解不是很到位,我便上网查资料,理解后缀表达式的含义,以及一个中缀表达式是如何转换成一个后缀表达式,接下来我思考如何利用本学期学习数据结构的知识来建立联系它们之间的关系,最终我选择了具有“先进后出”这一特点的栈结构来完成。
虽然说算法思想都有了,但实际操作起来并不是那么的容易,要将自己的思想转变为计算机语言来让计算机执行,不仅要掌握最基本的java语法知识,更为重要的一点便是要有较强的逻辑思维能力,循环开始的条件、循环的主体语句、循环结束的标志等这些都要搞明白,稍稍有一些的错误也许就会导致结果的错误。
另外,这次课程设计让我有一个深刻的体会,那就是细节决定成败,编程最需要的是严谨,往往检查了半天发现错误发生在某个括号,分号,引号,或者数据类型上。
程序设计时,也不要怕遇到错误,在实际操作过程中犯的一些错误还会有意外的收获,感觉课程设计很有意思。
在具体操作中将本学期所学的数据结构的理论知识得到巩固,达到课程设计的基本目的。
4.源程序代码
packagestudy_4;
importjava.util.*;
publicclassDesign{
/*将中缀表达式转化成为后缀表达式*/
privateArrayList<
String>
Convert(Stringexp){
//存放转化的后缀表达式的列表
ArrayList<
postExp=newArrayList<
();
StringBuffernumBuffer=newStringBuffer();
//存放一位数
OperatorStackopStack=newOperatorStack();
//操作符栈
charch,topChar;
//存放中缀表达式的元素、符号栈顶元素
opStack.push('
#'
);
//在符号栈压入'
,用来标记为栈底元素
try{
/*遍历中缀表达式*/
for(inti=0;
i<
exp.length();
){
ch=exp.charAt(i);
switch(ch){
/*若为运算符:
*则比较当前运算符与栈顶运算符的优先级*/
case'
+'
:
-'
*'
/'
topChar=opStack.peek();
//栈顶运算符
/*若栈顶运算符优先级>
=当前运算符优先级:
*则把栈中运算符优先级>
加入到后缀表达式列表中*/
while(Priority(topChar)>
=Priority(ch)){
postExp.add("
"
+topChar);
opStack.pop();
//栈顶运算符出栈,栈顶指针下移
topChar=opStack.peek();
//取栈顶元素
}
/*若栈顶运算符优先级
*则直接压入栈*/
opStack.push(ch);
i++;
break;
/*若为左括号:
*则直接压入栈*/
('
/*若为右括号:
*则直接把栈中左括号前面的运算符出栈,并加入后缀表达式
*/
)'
topChar=opStack.pop();
while(topChar!
='
postExp.add("
/*若为#号:
*则把栈中的操作符全部出栈,并加入后缀表达式*/
while(!
opStack.isEmpty()){
topChar=opStack.pop();
if(topChar!
)
postExp.add("
/*若为数字:
*则加入后缀表达式*/
default:
/*若为数字*/
if(ch>
='
0'
&
ch<
9'
while(ch>
numBuffer.append(ch);
ch=exp.charAt(++i);
}
postExp.add(numBuffer.toString());
numBuffer=newStringBuffer();
}
else{
thrownewError("
表达式输入错误!
请您检查表达式!
}
}//switch结束
}//for循环结束
}catch(RuntimeExceptione){
thrownewError(e.getMessage());
System.out.print("
后缀表达式为:
System.out.println(postExp.toString());
returnpostExp;
/*比较运算符优先级大小*/
privateintPriority(charop){
switch(op){
case'
return0;
return1;
return2;
表达式错误!
publicdoubleValue(Stringexp){
ArrayList<
postExp=Convert(exp);
//中缀表达式转化为后缀表达式
returndoValue(postExp);
//计算后缀表达式的值
/*计算后缀表达式的值*/
privatedoubledoValue(ArrayList<
postExp){
NumberStacknumStack=newNumberStack();
//数栈
Stringelement;
//存放后缀表达式的元素
doublenum_1,num_2,result;
//存放操作数、计算结果
/*遍历后缀表达式*/
postExp.size();
i++){
element=postExp.get(i);
从栈顶依次出栈两个操作数,计算出结果,再压入栈*/
if(isOperator(element)){
//返回String表示的操作数的double值
num_2=Double.parseDouble(numStack.pop());
num_1=Double.parseDouble(numStack.pop());
result=doOperate(num_1,num_2,element);
//将计算结果表示为字符串形式压入栈
numStack.push(newDouble(result).toString());
}
/*若为操作数,压入栈*/
else{
numStack.push(element);
/*遍历完后缀表达式:
栈顶元素出栈,即为后缀表达式的值*/
returnDouble.parseDouble(numStack.pop());
}catch(RuntimeExceptione){
thrownewError(e.getMessage());
/*判断是否为运算符*/
privatebooleanisOperator(Stringstr){
returnstr.equals("
+"
)||str.equals("
-"
*"
/"
/*计算两个操作数的值*/
privatedoubledoOperate(doublenum_1,doublenum_2,Stringop){
if(op.equals("
))
returnnum_1+num_2;
else
if(op.equals("
returnnum_1-num_2;
else
if(op.equals("
returnnum_1*num_2;
else
if(num_2==0){
thrownewError("
请注意除数不能为0!
}
else
returnnum_1/num_2;
publicstaticvoidmain(String[]args){
Designdesign=newDesign();
System.out.print("
请输入中缀表达式:
Scannersc=newScanner(System.in);
Strings=sc.next();
s=s+"
#"
;
doubleresult=design.Value(s);
表达式结果为:
System.out.println(result);
}
/*继承异常:
Java虚拟机正常运行期间抛出的异常,说明异常原因*/
classErrorextendsRuntimeException{
privatestaticfinallongserialVersionUID=1L;
publicError(Stringinfo){
super(info);
/*数栈:
用于辅助后缀表达式的值
*栈中的元素是字符串,因为数字有可能是两位或更高位的整数*/
publicclassNumberStack{
inttop;
//栈顶元素
Stringelements[];
//栈元素数组
intStackSize;
//栈最大元素
/*构造函数1*/
publicNumberStack(){
StackSize=100;
//缺省大小
elements=newString[StackSize];
top=-1;
//空栈的标志
/*构造函数2*/
publicNumberStack(intStackSize){
this.StackSize=StackSize;
/*判断栈是否为空*/
publicbooleanIsEmpty(){
returntop==-1;
/*判断栈是否满*/
publicbooleanIsFull(){
returntop==StackSize-1;
}
/*元素进栈*/
publicvoidpush(Stringitem){
if(IsFull())
return;
//栈满
//栈顶指针首先后移,在栈顶位置存放新元素
elements[++top]=item;
/*元素出栈*/
publicStringpop(){
if(IsEmpty())
return"
请检查您的表达式!
//返回一个数组中没有的元素
returnelements[top--];
//送出栈顶元素,栈顶指针下移
/*取栈顶元素*/
publicStringGetTop(){
!
表达是错误!
请检查您的表达式"
//栈空
returnelements[top];
//送出栈顶元素,栈顶指针不动
/*置空栈*/
publicvoidMakeEmpty(){
/*符号栈:
存放表达式的运算符*/
publicclassOperatorStack{
charelements[];
publicOperatorStack(){
elements=newchar[StackSize];
publicOperatorStack(intStackSize){
publicbooleanisEmpty(){
publicbooleanisFull(){
publicvoidpush(charitem){
if(isFull())
publiccharpop(){
if(isEmpty())
return'
'
publiccharpeek(){