数据结构与算法课程设计模拟简单计算器.docx
《数据结构与算法课程设计模拟简单计算器.docx》由会员分享,可在线阅读,更多相关《数据结构与算法课程设计模拟简单计算器.docx(20页珍藏版)》请在冰豆网上搜索。
数据结构与算法课程设计模拟简单计算器
…………………………………………………………………………装…………………………………………………..…………………………..订………………………………………………………………..………线…………………………………………………………….
通达学院算法与数据结构设计报告
(2014/2015学年第二学期)
题目:
模拟简单计算器
目录
一、课题内容和要求1
二、需求分析1
三、概要设计1
1设计理念1
2.子函数功能2
3.函数的调用4
四、详细设计4
五、测试及结果分析11
加法测试11
减法测试11
乘法测试12
除法测试12
混合运算13
六、调试过程中的问题13
七、课程设计总结15
一、课题内容和要求
利用所学的数据结构的基本知识,设计一个计算器(90)
输入:
带有括号、+,-,X,/的表达式;
输出:
运算结果
实例:
输入:
(4*3-(2+1))*2
输出:
18
要求:
1)对不合法输入进行检测并提示;
2)对合法输入求出正确解;
二、需求分析
本程序主要是采用栈的理论知识,主要用到两个结构体栈,一个用来转化表达式,一个用来计算表达式。
三、概要设计
1设计理念
首先,用一个字符数组来存储用户输入的中缀表达式。
然后用栈来把这个表达式转化为后缀表达式,转化时要进行符号优先级比较,这里将‘*’‘/’的优先级定为2,‘+’‘-’定为1,括号和‘=’定为0。
具体思想如下:
例如用户输入了1+2*3=,将其存放入一个字符数组中。
先在栈的底部存放一个‘=’号符,用作符号优先级比较。
首先将1存放到另外一个字符数组s1中,再将‘+’号入栈。
入栈的同时与底部的‘=’比较优先级,‘+’的优先级高于‘=’,所以不出栈,之后将2存放入s2中,然后再将‘*’入栈,入栈的同时与‘+’比较符号优先级,‘*’比‘+’高,所以不出栈。
再将3存入s2中。
之后将栈中不是‘=’的运算符都弹出栈,并依次存入s2中。
所以s2中的表达式为123*+。
之后进行计算,计算时用到浮点栈。
首先将s2中的字符依次入栈,遇到运算符时进行计算。
所以将123入栈后,再将‘*’入栈的同时,将前面两个数字进行运算,算出结果为6并存入栈中,之后再将‘+’入栈,再与1进行运算,结果即为7,然后输出结果。
2.子函数功能
pseqstack1init_seqstack1(void)
{
pseqstack1S;
S=(pseqstack1)malloc(sizeof(pseqstack1));
if(S)
S->top1=-1;
returnS;
}初始化栈
intempty_seqstack1(pseqstack1S)
{
if(S->top1==-1)
return1;
else
return0;
}
判断栈是否为空
intpush_seqstack1(pseqstack1S,datatype1X
进栈
intpop_seqstack1(pseqstack1S,datatype1*X)
出栈
intGetTop(seqstack*s)
取栈顶元素
intPP(charop,charc)
比较栈顶元素与当前读入的运算符的优先级
intOpe(inta,charm,intb)
从数字栈中取出的两个数的计算
intpriority(charop)
优先级判断函数
intinfix_exp_value(char*infixexp,char*postfixexp
将指针infixexp指向的中缀表达式转换为指针postfixexp指向的后缀表达式
doublepostfix_exp(char*A)
求后缀表达式的值
3.函数的调用
四、详细设计
#include
#include
#include
#definemaxsize100
typedefdoubledatatype1;
typedefchardatatype2;
typedefstructstack1
{
datatype1data1[maxsize];
inttop1;/*栈顶元素*/
}seqstack1,*pseqstack1;/*顺序栈*/
typedefstructstack2
{
datatype2data2[maxsize];
inttop2;/*栈顶元素*/
}seqstack2,*pseqstack2;/*顺序栈*/
/*栈的初始化*/
pseqstack1init_seqstack1(void)
{
pseqstack1S;
S=(pseqstack1)malloc(sizeof(pseqstack1));
if(S)
S->top1=-1;
returnS;
}
pseqstack2init_seqstack2(void)
{
pseqstack2S;
S=(pseqstack2)malloc(sizeof(pseqstack2));
if(S)
S->top2=-1;
returnS;
}
/*判断栈空*/
intempty_seqstack1(pseqstack1S)
{
if(S->top1==-1)
return1;
else
return0;
}
intempty_seqstack2(pseqstack2S)
{
if(S->top2==-1)
return1;
else
return0;
}
/*X入栈*/
intpush_seqstack1(pseqstack1S,datatype1X)
{
if(S->top1==maxsize-1)
{
printf("栈满,无法入栈!
\n");
return0;
}
else
{
S->top1++;
S->data1[S->top1]=X;
return1;
}
}
intpush_seqstack2(pseqstack2S,datatype2X)
{
if(S->top2==maxsize-1)
{
printf("栈满,无法入栈!
\n");
return0;
}
else
{
S->top2++;
S->data2[S->top2]=X;
return1;
}
}
/*X出栈*/
intpop_seqstack1(pseqstack1S,datatype1*X)
{
if(empty_seqstack1(S))
return0;
else
{
*X=S->data1[S->top1];
S->top1--;
return1;
}
}
intpop_seqstack2(pseqstack2S,datatype2*X)
{
if(empty_seqstack2(S))
return0;
else
{
*X=S->data2[S->top2];
S->top2--;
return1;
}
}
/*求栈顶元素*/
intgettop_seqstack1(pseqstack1S,datatype1*X)
{
if(empty_seqstack1(S))
return0;
else
*X=S->data1[S->top1];
return1;
}
intgettop_seqstack2(pseqstack2S,datatype2*X)
{
if(empty_seqstack2(S))
return0;
else
*X=S->data2[S->top2];
return1;
}
/*判断字符是否为操作数。
若是返回1,否则返回0*/
intisnum(charc)
{
if(c>='0'&&c<='9')
return1;
else
return0;
}
/*求后缀表达式的值*/
doublepostfix_exp(char*A)
{
pseqstack1S;/*定义栈S*/
doubleoperand=0;
doubleresult;/*存放栈顶元素*/
doublea;/*运算符ch前的操作数出栈存入a*/
doubleb;/*运算符ch后的操作数出栈存入b*/
doublec;/*c==achb*/
charch;/*存放读取到的表达式(A)的字符*/
ch=*A++;/*读表达式字符=>A*/
S=init_seqstack1();/*初始化栈*/
while(ch!
='#')/*遇到元素!
='#'时*/
{
if(isnum(ch))/*判断ch是否为数字字符,计算出操作数*/
operand=operand*10+(ch-'0');
else/*否则*/
{
if(operand)
{
push_seqstack1(S,operand);/*当前字符不是数字,操作数结束,要入栈*/
operand=0;
}
if(ch!
='@'&&ch!
='')
{
pop_seqstack1(S,&b);/*运算符ch后的操作数出栈存入b*/
pop_seqstack1(S,&a);/*运算符ch前的操作数出栈存入a*/
switch(ch)/*求achb==?
将结果赋给c*/
{
case'+':
c=a+b;
break;
case'-':
c=a-b;
break;
case'*':
c=a*b;
break;
case'/':
if(b!
=0)
c=a/b;
else
printf("分母为零!
");
}
push_seqstack1(S,c);/*将c压入栈中*/
}
}
ch=*A++;/*指针向下移动一位*/
}/*遇到'#'循环结束*/
gettop_seqstack1(S,&result);/*此时栈顶元素即为计算结果result*/
returnresult;
}
/*优先级判断函数*/
intpriority(charop)
{
switch(op)
{
case'#':
return1;
case')':
return2;
case'+':
case'-':
return3;
case'*':
case'/':
return4;
case'(':
return5;
default:
return0;
}
}
/*将指针infixexp指向的中缀表达式转换为指针postfixexp指向的后缀表达式*/
intinfix_exp_value(char*infixexp,char*postfixexp)
{
pseqstack2S;/*定义栈S*/
intcount=0;
charw;/*存放读取到的表达式(infixexp)的字符*/
charc;/*存放栈顶元素*/
chartopelement;/*存出栈元素*/
S=init_seqstack2();/*初始化栈*/
if(!
S)/*栈的初始化判断*/
{
printf("栈初始化失败!
");
return0;
}
push_seqstack2(S,'#');/*将结束符'#'加入运算符栈S中*/
w=*infixexp;/*读表达式字符=>w*/
while((gettop_seqstack2(S,&c),c)!
='#'||w!
='#')/*<3>栈顶元素不等于'#'或w不等于'#'时循环*/
{
if(isnum(w))/*判断w是否为操作数,若是直接输出,读下一个字符=>w,转<3>*/
{
if(count)
{
*postfixexp='@';
postfixexp++;
count=0;
}
*postfixexp=w;
postfixexp++;
w=*(++infixexp);
}
else/*w若是运算符分类如下*/
{
count=1;
if((gettop_seqstack2(S,&c),c)=='('&&w==')')
{/*如果栈顶为'('并且w为')'则'('出栈不输出,读下一个字符=>w,转<3>*/
pop_seqstack2(S,&topelement);/*将'('出栈存入topelement*/
w=*(++infixexp);
}
else
if((gettop_seqstack2(S,&c),c)=='('||priority((gettop_seqstack2(S,&c),c)){/*如果栈顶为'('或者栈顶优先级小于w优先级,则w入栈,读下一个字符=>w,转<3>*/
push_seqstack2(S,w);
w=*(++infixexp);
}
else/*否则*/
{/*从运算符栈中出栈并输出,转<3>*/
pop_seqstack2(S,&topelement);
*postfixexp=topelement;
postfixexp++;
}
}
}
*postfixexp='#';/*在指针postfixexp指向的后缀表达式结尾追加字符'#'*/
*(++postfixexp)='\0';/*在指针postfixexp指向的后缀表达式最后追加结束符'\0'*/
return1;
}
/*主函数*/
intmain()
{
inti=0;
charA[maxsize];
charB[maxsize];
printf("请输入表达式,如:
11+22#,必须以#号结尾!
\n");
/*1+2*(9+7)-4/2#23+((12*3-2)/4+34*5/7)+108/9#*/
A[i]=getchar();
while(A[i++]!
='#')
{
A[i]=getchar();
}
A[i]='\0';
infix_exp_value(A,B);
printf("A==%s\n",A);
printf("B==%s\n",B);
printf("上式的结果为:
");
printf("%g\n",postfix_exp(B));
return0;
getch();
}
五、测试及结果分析
加法测试
1+2+3=6
减法测试
5-2-1=2
乘法测试
1*2*3=6
除法测试
9/3/2=1.5
混合运算
1*(3+2)
六、调试过程中的问题
函数doublepostfix_exp(char*A)修改前后对比
函数intinfix_exp_value(char*infixexp,char*postfixexp)修改前后对比
七、课程设计总结
通过这一周的课程设计,模拟简单计算器算法有了初步的了解。
这次实验虽然时间不长,但是,我还是收获了许多,首先,要完成一个课程设计师需要我们有严谨的科学态度和扎实的理论知识作为基础和后盾的;其次,还要将理论知识与实际课题相结合,融会贯通。
虽然我们之前对数据结构和C语言的联合使用并不熟悉,但通过老师的详细讲解和指导、及同学的互相帮助,最终完成了本次课程设计。
在这次课程设计中,我们还存在着有待改进和完善的地方,还需要我们更加深入的去学习和了解这方面的知识,用更加完善的知识储备和自己的思考能力相结合,相信能够将此次课程设计做的更好,也能更好的提高自己的综合素质和能力!