C语言_算数表达式求值_课程设计报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录
一.概述1
二.总体方案设计2
三.详细设计3
四.程序的调试与运行结果说明4
五.课程设计总结5
参考文献错误!未定义书签。

附录 (8)
一概述
一、课程设计的目的与要求
本课程设计是为了配合?数据构造?课程的开设,通过设计一个完
整的程序,使学生掌握数据构造的应用,算法的编写,类C语言的算法转换成C程序并用Turbo C2.0或Visual C++6.0上机调试的根本方法。

要求如下:
1.要充分认识课程设计对自己的重要性,认真做好课程设计前的各项准备工作。

2.既要虚心承受教师的指导,又要充分发挥主观能动性.结合课题,独立思考,努力钻研,勤于实践,勇于创新。

3.独立按时完成规定的工作任务,不得弄虚作假,不准抄袭他人容,否那么成绩以不及格计。

4.课程设计期间,无故缺席按旷课处理;缺席时间达四分之一以上者,其成绩按不及格处理。

5.在设计过程中,要严格要求自己,树立严肃,严密,严谨的科学态度,必须按时,按质,按量完成课程设计。

6.小组成员之间,分工明确,但要保持联系畅通,密切合作,培养良好的互相帮助和团队协作精神。

二、需求分析
本课程设计的课题为表达式求值,要求:
1.用户将表达式原样输入〔在表达式结尾加上#〕,能得出结果〔为减小难度,运算结果的10进制形式的值,不超过longdouble的存储围〕;
2.输入的数可以为小数〔为减小难度,小数的整数与小数局部均不超过10位〕,负数〔如果负数前有运算符,那么应将负数括起来〕,以及2进制,8进制,10进制,16进制的数〔为减小难度,数出的结果都以10进制形式表示〕;
3.运算符号包括〔〕、+、—、*、/;括号可以多重;
二总体方案设计
1.使用双链表的数据构造表示数据的存储,将用户输入的表达式以字符形式存入双链表中。

2.对以负数开头、以括号开头、左括号后紧跟负数的特殊情况作处理。

3.将数与运算符分开;
4.依次找到表达式最层括号,次层括号..................每次找到括号的表达式,便将其进展只有加减乘除运算的计算。

构造体类型:
//用来存储字符的结点类型
typedef struct CharNode
{
char c;
struct CharNode *next;
}CharNode;
//用来存储数的结点类型
typedef struct IntNode
{
long double i;
struct IntNode *next;
}IntNode;
//用来存储数的结点类型
typedef struct Node
{
long double n;
struct Node_ys_char *next;
}Node;
//用来存储运算符的结点类型
typedef struct Node_ys_char
{
char c;
struct Node_ys_char *next_c;
struct Node *next;
}Node_ys_char;
三详细设计
我任务是整个程序的算法设计,以及局部子函数的编写,经过其他组员编写的子函数的处理,将表达式变为一个普通的表达式,其中数与运算符已经分开,将这个表达式的头指针传递到我所编写函数中,运算思想为:找到最层的一对括号,计算括号间的表达式的值,得到值之后,用这个值替换掉原始位置上的一对括号,以及其中的表达式。

例如〔〔〔6.5-2*2.25〕*2-6〕/2+1.5〕+3#,第一次替换后为〔〔2*2-6〕/2+1.5〕+3#,第二次替换后为〔-2/2+1.5〕+3#,第三次
替换后为0.5+3#,当没有括号时调用四那么运算函数直接计算。

如果一开场输入的表达式中没有括号,那么直接调用四那么运算函数进展计算。

整个程序的算法思想见流程图。

主要局部的详细流程图〕
四 6+2*3+1#结果正确,而当计算6-2*3+1#时,却得出+1;这是因为先计算2*3得到
6;表达式变为6-6+1#;接着进展6+1的运算,得到7;当前计算循序错误,导致结果错误。

后来将程序改为先进展优先级高的运算符的运算,当优先级相等时,不计算。

指针后移,当遇到表达式完毕标志时,便将指针移到表达式的头位置,此时,判断是否进展运算的条件发生变化,当前后运算符的优先级相等时,进展前面运算符的运算;使得第一次将乘除运算符运算完,第二进展只有加减运算符的运算
五课程设计总结
进过调试程序能得出大多数表达式的正确结果,虽然经过了一些特殊情况表达式的输入,得出了正确结果,但不排除还有某些漏洞使得一些特殊情况的表达式不能得出正确结果,还有待进一步的测试。

特点:本程序能进展小数、以及2进制、8进制、16进制的运算。

缺乏:结果都以10进制形式表示,用户不能改变;结果的10进制形式不能超出longdouble型数据能存储的数的围;
进一步的设想:将数分段存储,存动态分配,使其能进展天文数字运算;录入其他的运算符例如指数运算,开方运算,取余运算,解一元一次方程,解二元一次方程组。

附录:
源代码:
//用来存储字符的结点类型
typedef struct CharNode
{
char c;
struct CharNode *next;
}CharNode;
//用来存储数的结点类型
typedef struct IntNode
{
long double i;
struct IntNode *next;
}IntNode;
//用来存储数的结点类型
typedef struct Node
{
long double n;
struct Node_ys_char *next;
}Node;
//用来存储运算符的结点类型
typedef struct Node_ys_char
{
char c;
struct Node_ys_char *next_c;
struct Node *next;
}Node_ys_char;
char Precede(char x,char y)//运算符优先级判断{
int i,j;
int from[5][5]
={
{0,0,-1,-1,0},
{0,0,-1,-1,0},
{1,1,0,0,1},
{1,1,0,0,1},
{0,0,-1,-1,0}
};//定义一个二维数组存放算术符号的优先级switch(x)
{
case '+':i=0;break;
case '-':i=1;break;
case '*':i=2;break;
case '/':i=3;break;
case '#':i=4;break;
}
switch(y)
{
case '+':j=0;break;
case '-':j=1;break;
case '*':j=2;break;
case '/':j=3;break;
case '#':j=4;break;
}
if(from[i][j]==1)//说明运算符i的优先级比j的优先级高return '>';
if(from[i][j]==-1)
return '<';
else
return '=';
}
//输入表达式,并对特殊情况做处理
CharNode *CreatRegister()
{
CharNode *top,*p,*q,*e;
top=(CharNode *)malloc(sizeof(CharNode));
p=q=top;
scanf("%c",&p->c);
scanf("%c",&p->c);
if(q->c=='-')
{
p=(CharNode *)malloc(sizeof(CharNode));
p->c='0';
p->next=q;
top=p;
p=q;
}
if(q->c=='(')
{
e=(CharNode *)malloc(sizeof(CharNode));
e->c='0';
p=(CharNode *)malloc(sizeof(CharNode));
p->c='+';
e->next=p;
p->next=q;
p=q;
top=e;
}
while(p->c!='#')
{
q=(CharNode *)malloc(sizeof(CharNode));
scanf("%c",&q->c);
if((p->c=='(')&&(q->c=='-'))
{
e=(CharNode *)malloc(sizeof(CharNode));
e->c='0';
e->next=q;
p->next=e;
p=q;
}
else
{
p->next=q;
p=q;
}
}
p->c='+';
p->next=(CharNode *)malloc(sizeof(CharNode));
p->next->c='0';
p=p->next;
p->next=(CharNode *)malloc(sizeof(CharNode));
p->next->c='#';
return top;
}
//将数与运算符分开,并将其他进制转化为10进制Node *StackChange(CharNode *top,int m)
{
CharNode *p,*q;
long double x=0,y=0;
char a[10],b[10];
int n=0,i=0,JiWei,max,min=47,mark_1=0,mark_2=0,h,k=0; Node *node,*head;
Node_ys_char *node_char;
switch(m)
{
case 2:
JiWei=2;
max=50;
break;
case 8:
JiWei=8;
max=56;
break;
case 10:
JiWei=10;
max=97;
break;
case 16:
JiWei=16;
max=103;
break;
}
p=q=top;
while(p->c !='#')
{
while((q->c>min)&&(q->c<max)||(q->c==46))
{
if(q->c==46)
{
mark_1=1;
q=q->next;
}
if(mark_1==0)
{
a[n]=q->c;
q=q->next;
n++;
}
if(mark_1==1)
{
b[i]=q->c;
q=q->next;
i++;
}
}
for(h=n-1;h>=0;h--)
{
x=(a[n-h-1]-48)*pow(JiWei,h)+x;//
}
for(h=0;h<i;h++)
{
y=y+(b[h]-48)*pow(JiWei,(-(h+1)));//
}
node=(Node *)malloc(sizeof(Node));//
node->n=x+y;
mark_1=0;
n=0;
i=0;
if(mark_2==1)
node_char->next=node;
node_char=(Node_ys_char *)malloc(sizeof(Node_ys_char)); node_char->c=q->c;
node->next=node_char;
node_char->next_c=NULL;
node_char->next=NULL;
if(q->c=='#')
{
node->next=(Node_ys_char *)malloc(sizeof(Node_ys_char));
node->next->c='#';
return head;
}
q=q->next;
if(q->c<=min)
while(q->c<=min)
{
node_char->next_c=(Node_ys_char*)malloc(sizeof(Node_ys_char));
node_char->next_c->c=q->c;
q=q->next ;
//node->next=node_char;
node_char=node_char->next_c;
node_char->next_c=NULL;
node_char->next=NULL;
}
else
{
node->next=node_char;
node_char->next_c=NULL;
node_char->next=NULL;
}
p=q;
n=0;
x=0;
y=0;
if(mark_2==0)
{
head=node;
mark_2=1;
}
}
return head;
}
//作只有加减乘除运算的表达式求值
Node *Compute(Node *p)
{
int mark=0;
Node *m,*n;
char max_char,min_char;
m=n=p;
while(p->next->c!='#')
{
max_char=n->next->c;
n=n->next->next;
min_char=n->next->c;
if((Precede(max_char,min_char)=='<'||Precede(max_char,min_char)=='=')&&mark!=1) {
m=n;
}
if(Precede(max_char,min_char)=='>'||mark==1)
{
switch(m->next->c)
{
case '+':m->n =m->n + n->n ;break;
case '-':m->n =m->n - n->n ;break;
case '*':m->n =m->n * n->n ;break;
case '/':m->n =m->n / n->n ;break;
}
m->next=n->next;
n=m;
}
if(m->next->c=='#')
{
m=n=p;
mark=1;
}
}
return m;
}
//求用户输入表达式的值
Node *GetOutcome(Node *head)
{
Node *p,*q,*R;
Node_ys_char *m,*n,*t,*k;
n=(Node_ys_char *)malloc(sizeof(Node_ys_char));
n->c='(';
p=q=head;
while((n->c!=')')&&(q->next->c!='#'))
{
if(q->next->c=='(')
{
m=q->next;
k=m;
}
else if(q->next->next_c==NULL)
q=q->next->next;
else
{
m=q->next->next_c;
k=q->next;// t=q->next;
if(m->c=='(')
{
t=k;
k=m;
}
while(m->next_c!=NULL)
{
m=m->next_c;
if(m->c=='(')
{
t=k;
k=m;
}
}
q=m->next ;
}
if(q->next->c==')')
{
n=q->next;
}
}
if(n->c==')')
{
p=k->next;
q->next->c='#';
R=Compute(p);
t->next =R;
t->next_c=NULL;
R->next=n->next_c;
GetOutcome(head);
}
else
{
R=Compute(head);
return R;
}
}
main()
{
int m;//进制
char a;
CharNode *top_1;
Node *top_2,*R;
printf("\n\n");
printf("███████████████████████████████████████\n");
printf("████\n");
printf("██表达式求值系统██\n");
printf("████\n");
printf("███████████████████████████████████████\n");
printf("本程序可分别进展2进制,8进制,10进制,16进制的加减乘除运算:\n");
loop:
printf("...............请输入进制..............\n");
printf("你选的进制为:");
scanf("%d",&m);
printf("请输入表达式,表达式请以#结尾:\n");
top_1=CreatRegister();//录入表达式,并对特殊情况作处理,将头指针带回;
top_2=StackChange(top_1,m);//进制转换,将数与运算符分开,将头指针带回;
R=GetOutcome(top_2);得出结果
printf("运算结果的十进制形式为:\n");
printf("%lf",R->n);
printf("\n继续进展运算请输入y否那么退出:\n");
scanf("%c",&a);
scanf("%c",&a);
if(a=='y'||a=='Y')
goto loop;
}
运行结果:。

相关文档
最新文档