模拟计算器.算术表达式的求解
【问题描述】
给定一个算术表达式,通过程序求出最后的结果。
【实现要求】
(1)数值:包括整数和实数,数值可带正、负号。
(2)运算符:正号、负号、加、减、乘、除、求模和乘方,其中可以包含括号。
【实现提示】
(1)从键盘输入要求解的算术表达式;
(2)采用二叉树进行算术表达式的求解过程;
(3)能够判断算术表达式正确与否;
(4)对于错误表达式给出提示;
(5)对于正确的表达式给出最后的结果;
【程序代码】
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define num_MAX 10000000
typedef struct TNode{
int flag;
int data;//flag=0
char ch;//flag=1
struct TNode * lChild;//左孩子
struct TNode * rChild;//右孩子
}BiNode,*BiTree;
int cal(BiTree T)
{//判断是数字还是符号
if(T->flag==1) //如果是字符,进行switch分支选择语句
{
switch(T->ch)
{
case '+': //加运算
return cal(T->lChild)+cal(T->rChild);
break;
case '-': //减运算
return cal(T->lChild)-cal(T->rChild);
break;
case '/': //除运算,除号不为零
if(cal(T->rChild)!=0)
return cal(T->lChild)/cal(T->rChild);
break;
case '*': //乘运算
return cal(T->lChild)*cal(T->rChild);
break;
case '%': //模运算
return cal(T->lChild)%cal(T->rChild);
break;
case '^': //乘方运算
float sum=1;
for(int i=0;i<cal(T->rChild);i++)
{
sum*=cal(T->lChild);
}
return sum;
break;
}
}
return T->data;
}
int check(char s[],int start,int end) //检查输入情况
{
int i;
int sum=0;
int flag=1; //正数
for(int i=start;i<=end;i++)
{
if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')) //当输入字母时,返回-1
return -1;
}
for(int i=start;i<=end;i++)
{
if(s[i]=='#')
return 1;
}
if(s[start]=='-') //如果一开始为负数
{
flag=-1;
start++;
}
for(i=start;i<=end;i++)
{
if(!isdigit(s[i])) //如果不是是数字
return num_MAX;
sum=sum*10+s[i]-'0';//如果是数字
}
return sum*flag;
}
BiTree buildTree(char s[],int start,int end)//建立二叉树
{
BiTree T=(BiTree)malloc(sizeof(BiNode));//向内存申请空间
if(start>end)
return NULL;
int pos1=0;//加减号位置
int num1=0;//加减号个数
int pos2=0;//乘除号位置
int num2=0;//乘除号个数
int pos3=0;//模乘方位置
int num3=0;//模乘方个数
int num;
num=check(s,start,end);
if(num!=num_MAX) //只有数字
{
T->flag=0;
T->data=num;
T->lChild=NULL;
T->rChild=NULL;
return T;
}
//有操作符
int in_brackets=0;//在括号里的标识符
for(int k=start;k<=end;k++)
{
if(s[k]=='(') //括号
{
in_brackets++;
}
else if(s[k]==')')
{
in_brackets--;
}
else if(!in_brackets) //括号之外 或者没有括号的算式
{
if(s[k]=='+'||s[k]=='-')
{
pos1=k;
num1++;
}
else if(s[k]=='*'||s[k]=='/')
{
pos2=k;
num2++;
}
else if(s[k]=='%' || s[k]=='^')
{
pos3=k;
num3++;
}
}
}
int pos_T;
//寻找根节点 有加减用加减没加减用乘除 //(1+1)*2
if(num1)
{
pos_T=pos1;
}
else if(num2)
{
pos_T=pos2;
}
else if(num3)
{
pos_T=pos3;
}
else{//找不到根 递归再找一次
return buildTree(s,start+1,end-1); // 11+22*3-16/4
}
T->flag=1;
T->ch=s[pos_T];
T->lChild = buildTree(s,start,pos_T-1);
T->rChild = buildTree(s,pos_T+1,end);
return T;
}
int main()
{
while(1){
int m;
char a[200];
printf("请输入表达式:"); //键盘输入算术表达式
scanf("%s",a);
m=check(a,0,strlen(a));
if(m==-1) //判断算术表达式是否正确
{
printf("输入错误表达式!"); //错误表达式提示
return 0;
}
if(m==1) //判断用户是否要求退出,#为退出指示
{
printf("程序结束运行!"); //程序退出提示
return 0;
}
printf("你输入的表达式结果为:%s=",a);//正确输出结果
BiTree b=(BiTree)malloc(sizeof(BiTree));
b=buildTree(a,0,strlen(a)-1);
printf("%d\n",cal(b));
}
return 0;
}
【运行结果】
程序主界面如图所示
错误表达式提示如图所示
cal加减乘除乘方模运算如图所示
程序退出如图所示