余哥大一,是个C新手,有一天突然想写一个四则计算器。苦思无果,遂去问班内c大神。
我:大神,我想写个计算器,有优先级的那种。
大神:嗯……
我:大神你写过吗?
大神:嗯…….
我:那大神用什么写的?
大神:逆波兰式。
我:………
我:请具体一点…..
大神:两个栈解决问题…..
我:…..
我:那个请问一下栈是什么?
大神:……
大神:不知道。滚!
哼!不教就不教,我还不稀罕呢。老子自己写一个。哼!我又不是没写过
初级计算器。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b,c;
printf("这是一个加法计算器,欢迎您使用!\n");
printf("---------------------------\n");
printf("请输入第一个数(输入完毕后请按回车)\n");
scanf("%d",&a);
printf("请输入第二个数(输入完毕后请按回车)\n");
scanf("%d",&b);
c=a+b;
printf("它们的和是%d\n", c);
system("pause");
return 0;
}
(看完代码)我:呃……好像没什么卵用!
哼!不管!我就是要写出计算器。说干就干,凭借着我聪明的大脑和英俊的面庞(这个是重点),在经历思想与灵魂的碰撞之后终于写出来了一个带有优先级的计算器。以下是我的心路历程。
第一步:
分析一个了简单的四则运算的表达式,我觉得用链表存储数据比较合适。
结构体代码如下:
typedef struct _shuju
{
int b;//存储数
char x;//存储符号
struct _shuju*next;
}shu;
第二步:
连用什么数据结构写都想出来了,我真是天才。喝口茶,看看大姐姐,放松一下心情。等下再写。
第三步:
确定输入,把四则表达式两两拆开,建立链表,最后没有符号的就存'#'。
结果如下:
shu*input()
{
int i=0,l=1,q=0;//i用来做ch的下标,l好像没什么用,q好像也没用
char c,ch[20]={0},lc=0;
shu*b1,*b2,*head;
b1=b2=head=(shu*)malloc(len);
while((c=getchar())!='\n')
{
if(c=='*'||c=='/'||c=='-'||c=='+')//遇到运算符建立一个链表节点
{
i=0;//每次链表节点建立完毕ch从头在来
b1->x=c;
b1->b=atoi(ch);//将字符串转化为整型
memset(ch,0,sizeof(ch));//释放ch
b1=(shu*)malloc(len);
b2->next=b1;
b2=b1;
}
else
ch[i++]=c;//ch存储0-9的字符
}
b1->x='#';
b1->b=atoi(ch);
b1->next=NULL;
return head;
}
然后是输出,通过链表的遍历,计算数值。那怎么先乘除后加减呢?其实只要在遍历链表时先算乘除就好了。
代码如下:
int shuchu(shu*head)
{
shu*pd=head,*pl;
while(pd!=NULL)
{
if(pd->x=='*'||pd->x=='/')//先乘除
{
pl=pd->next;
if(pd->x=='*')
pd->b*=pl->b;
if(pd->x=='/')
pd->b/=pl->b;
pd->x=pl->x;
pd->next=pl->next;
}
else
pd=pd->next;
}
pd=head;
while(pd!=NULL)
{
if(pd->x=='+'||pd->x=='-')//后加减
{
pl=pd->next;//链表遍历遇到'+' '-'时停下 将当前节点的next节点赋给 pl
if(pd->x=='+')
pd->b+=pl->b; //两个数值相加
if(pd->x=='-')
pd->b-=pl->b;
pd->x=pl->x;//将pl的符号赋值给pd
pd->next=pl->next; //抛弃pl
}
else
pd=pd->next;//没遇到加减 pd等于它下一个节点 遇到了的话 pd运算完后还是pd
}
return head->b;//返回最后的结果
}
主函数是
int main()
{
shu*pd;
pd=input();
printf("%d",shuchu(pd));
getchar();
getchar();
}
第四步:
以上的代码就完成了一个有加减乘除优先级的计算器。接下来就是括号和乘方了。初步决定在建立主链表时,
遇到一个括号就建立一个副链表,括回来时计算括号内链表的值,整个括号变成一个值建立在主链表上。
最终代码入下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define len sizeof(shu)
typedef struct _lala
{
int b;//存储数值大小
char x;//存储运算符号
struct _lala*next;//进行链表链接
}shu;
shu*input();//输入时创建链表
int shuchu(shu*);//用链表的遍历 进行四则运算返回一个整型
int kuohao()//将括号里的元素建立一个链表并求值
{
shu*head;
head=input();
return shuchu(head);
}
shu*input()
{
int i=0,l=1,q=0;//i用来做ch的下标,l好像没什么用,q好像也没用
char c,ch[20]={0},lc=0;
shu*b1,*b2,*head;
b1=b2=head=(shu*)malloc(len);
while((c=getchar())!='\n'&&c!=')')
{
if(c=='(') //遇到'('则新建一个链表 并且遇到 ')'链表退出建立 计算出括号内的值后
{
itoa(kuohao(),ch,10); //将整型转化为字符串 将这个括号里的元素用返回的值代替连接在主链表上
}
else
{
if(c=='^')
{
c=getchar();
l=c-48;
itoa(pow(atoi(ch),l),ch,10);
continue;
}
if(c=='*'||c=='/'||c=='-'||c=='+')//遇到运算符建立一个链表节点
{
i=0;//每次链表节点建立完毕ch从头在来
b1->x=c;
b1->b=atoi(ch);//将字符串转化为整型
memset(ch,0,sizeof(ch));//释放ch
b1=(shu*)malloc(len);
b2->next=b1;
b2=b1;
}
else
ch[i++]=c;//ch存储0-9的字符
}}
b1->x='#';
b1->b=atoi(ch);
b1->next=NULL;
return head;
}
int shuchu(shu*head)
{
shu*pd=head,*pl;
while(pd!=NULL)
{
if(pd->x=='*'||pd->x=='/')//先乘除
{
pl=pd->next;
if(pd->x=='*')
pd->b*=pl->b;
if(pd->x=='/')
pd->b/=pl->b;
pd->x=pl->x;
pd->next=pl->next;
}
else
pd=pd->next;
}
pd=head;
while(pd!=NULL)
{
if(pd->x=='+'||pd->x=='-')//后加减
{
pl=pd->next;//链表遍历遇到'+' '-'时停下 将当前节点的next节点赋给 pl
if(pd->x=='+')
pd->b+=pl->b; //两个数值相加
if(pd->x=='-')
pd->b-=pl->b;
pd->x=pl->x;//将pl的符号赋值给pd
pd->next=pl->next; //抛弃pl
}
else
pd=pd->next;//没遇到加减 pd等于它下一个节点 遇到了的话 pd运算完后还是pd
}
return head->b;
}
int main()
{
shu*pd;
pd=input();
printf("%d",shuchu(pd));
getchar();
getchar();
}
完。