面向对象课程设计报告格式.docx
《面向对象课程设计报告格式.docx》由会员分享,可在线阅读,更多相关《面向对象课程设计报告格式.docx(13页珍藏版)》请在冰豆网上搜索。
面向对象课程设计报告格式
题目:
计算器
学号:
1004681035
姓名:
李博洋
班级:
计科101
1、需求分析:
题目:
设计一个简单的计算器
要求:
在功能上功能尽量模拟windows操作系统中的计算器,系统界面不做强制要求。
分析:
输入或从文件中读入需要计算的式子,然后计算出正确的结果,将结果输出。
解析:
得到一个需要计算的式子,很显然这个式子中包含着数字以及各种运算符和括号,这个式子是一个字符串,因而要用到string。
在数据结构中,一个算术表达式就是一个按中序遍历的二叉树,如果要计算,很显然要将该式子按后续遍历(逆波兰式),得到按优先级排列的便于计算的式子,中间过程需要用到栈(stack),计算过程也要用到栈,因而创建了一个链栈的模板,在需要的时候,按需要的类型实例化就可以了。
操作流程:
菜单界面--->选择输入的方式---->按不同的输入方式读取信息---->将计算式子按逆波兰式转化---->计算---->输出结果
2、概要设计
template
classNode{
public:
Node(){this->next=NULL;}
Node(Tdata,Node*next=NULL){this->data=data;this->next=next;}
Tdata;
Node*next;
}
明确设计为链表类型的存储结构,因而节点(Node)就必须包含一个需要存储类型数据成员,还应有一个指向下一个节点的指针,用构造函数初始化个数据成员。
将数据成员定义为public是为了下面的访问方便。
template
classLinkedStack{
public:
LinkedStack();
~LinkedStack();
boolisEmpty();
voidpush(Tx);
Tpop();
TgetTop();
private:
Node*top;
};
根据需要,要用到多种类型的栈(stack),而栈的功能都大体相同,所以将类设计为模板类(template),这样在需要用的时候实例化就可以用了。
创建链栈,就要用到上面的节点(Node).栈的主要功能有初始化(LinkedStack()),入栈(voidpush(Tx)),出栈(Tpop()),得到栈顶元素(TgetTop()),还有可能判断栈是否为空栈(boolisEmpty()),然后分别将各个部分实现。
3、程序编码。
程序的流程图如下:
计算过程
成功
继续
失败
计算过程
部分重点代码注释详见程序清单。
4、调试分析
分模块(类)进行,设计好测试数据,测试输出的结果,时间复杂度分析,和每个模块设计和调试时存在问题的思考(问题是哪些问题如何解决),算法的改进设想。
菜单界面。
选择读取方式...
从键盘读入表达式,并计算得出结果。
继续从键盘读入
选择从文件读入,并且文件打开成功
输入文件中的算术表达式
输出文件中的结果
调试时存在的问题:
刚开始时,链表的链接存在问题,老是出现内存访问错误,最后通过调试发现,原来多写了一个next。
然后就是在写tochange()函数时,switch语句中的条件考虑的不够全面。
再就是string类型的表达式不能够作为switch的条件。
最后就是定义了一个stringa,不能够通过a[i]="2as"这种方式给string类型的数据赋值
算法的改进设想:
在分配expression的时候,都是按的比较大的值分配的,有很多空间都没有用到,造成了很多内存的浪费。
改进:
运用链表,动态的分配,按需分配
程序清单:
#include
#include
#include
#include
usingnamespacestd;
template//链表节点类
classNode
{
public:
Node()//defaultconstructor
{
this->next=NULL;
}
Node(Tdata,Node*next=NULL)
{
this->data=data;
this->next=next;
}
//声明为public类型是便于top的访问
Tdata;
Node*next;//next指向的对象是Node,
};
template
classLinkedStack
{
public:
LinkedStack();//defaultconstructor
~LinkedStack();//defaultdestructor
boolisEmpty();
voidpush(Tx);
Tpop();
TgetTop();
private:
Node*top;
};
template
LinkedStack:
:
LinkedStack()
{
top=NULL;
}
template
LinkedStack:
:
~LinkedStack()
{
Node*p=top;
Node*q;
while(p!
=top)//将编表所分配的空间一个一个给释放掉
{
q=p;
p=p->next;
deletep;
}
top=NULL;
}
template
boolLinkedStack:
:
isEmpty()
{
returntop==NULL;
}
template
voidLinkedStack:
:
push(Tx)
{
top=newNode(x,top);//将链表给链接起来,并且更新top指向的位置
}
template
TLinkedStack:
:
pop()
{
if(!
isEmpty())
{
Tx=top->data;
Node*p=top;
top=top->next;
deletep;
returnx;
}
throw"空栈,不能执行出栈操作";
}
template
TLinkedStack:
:
getTop()
{
if(!
isEmpty())
{
returntop->data;
}
throw"空栈,不能获得栈顶元素";
}
stringtochange(stringexpression)//非递归后序遍历,将输入的计算表式//按后续遍历的顺序放到postfix中去逆波兰式
{
LinkedStackstack;//模板用char实例化了
charpostfix[100];
inti=0,j=0;charout;
while(expression[i]!
='\0')//逆波兰式算法,将中序的算术表达式转化成为后续的式子
{
switch(expression[i])///将expression中的每个字符对号入座
{
case'+':
case'-':
while(!
stack.isEmpty()&&stack.getTop()!
='(')
{
postfix[j++]=stack.pop();
}
stack.push(expression[i++]);
break;
case'*':
case'/':
while(!
stack.isEmpty()&&(stack.getTop()=='*'||stack.getTop()=='/'))
{
postfix[j++]=stack.pop();
}
stack.push(expression[i++]);
break;
case'(':
stack.push(expression[i++]);
break;
case')':
out=stack.pop();
while(!
stack.isEmpty()&&out!
='(')
{
postfix[j++]=out;
out=stack.pop();
}
i++;
break;
default:
while(expression[i]>='0'&&expression[i]<='9')
{
postfix[j++]=expression[i++];
}
postfix[j++]='';//输入空格是方便下面的计算
}
}
while(!
stack.isEmpty())
{
postfix[j++]=stack.pop();
}
postfix[j]='\0';//将postfix数组最后补上\0,表示结尾
returnpostfix;
}
intvalue(stringpostfix)//计算
{
LinkedStackstack;//模板用int实例化了,用于存放int型数据
inti=0;
intresult=0;
while(postfix[i]!
='\0')
{
if(postfix[i]>='0'&&postfix[i]<='9')
{
result=0;
while(postfix[i]!
=''){
result=result*10+postfix[i++]-'0';
}
i++;
stack.push(result);
}
else
{
if(postfix[i]!
='')
{
inty=stack.pop();
intx=stack.pop();
switch(postfix[i])
{
case'+':
result=x+y;
break;
case'-':
result=x-y;
break;
case'*':
result=x*y;
break;
case'/':
result=x/y;
break;
}
stack.push(result);
}
i++;
}
}
returnstack.pop();
}
intmain()
{
cout<<"******************计算器******************"<cout<<"(ByLby)"<cout<cout<<"请选择您想要执行的操作:
"<cout<<"1.从键盘输入2.从文件读取"<intt;
cin>>t;
switch(t)
{
case1:
{
intm=1;
while(m)
{cout<<"请输入算式!
"<stringa;
cin>>a;
stringpostfix=tochange(a);
cout<cout<cout<<"继续?
1.是0.否";
cin>>m;
}
break;
}
case2:
{
ifstreamin;
ofstreamout;
in.open("math.in");
out.open("result.out");
if(!
in)
{
cerr<<"Failtoopenthefile,pleasecheck!
!
!
"<exit(0);
}
inti=0;intm=0;
stringexpression[100];
while(getline(in,expression[i++]));
m=i-1;
for(i=0;i{
stringpostfix=tochange(expression[i]);
out<out<}
in.close();
out.close();
}
}
return0;
}