//假设各运算符和运算数之间均有空格
//检验中缀表达式是否合法并计算结果
//用两个栈,一个存运算数,一个存运算符
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
char operators[100];//运算符
double operand[100];//运算数
int topr=-1;
int topd=-1;
int getresult(char ch){//由运算符得到当前运算结果
if(topd<1)
return 0;
double number1=operand[topd--];
double number2=operand[topd--];
if(ch=='+')
operand[++topd]=number1+number2;
else if(ch=='-')
operand[++topd]=number2-number1;
else if(ch=='*')
operand[++topd]=number1*number2;
else if(ch=='/'){
if(fabs(number1)<=0.0000000001)
return 0;
operand[++topd]=number2/number1;
}
return 1;
}
int cal(char ch)//处理每个运算符和两个( )
{
//此处的一个bug调了半天没发现->用i去遍历operators了,也就每次处理完当前运算符,未topr--;
int flag=1;
if(ch=='('){
operators[++topr]=ch;
}
else if(ch==')'){
for(;topr>=0&&operators[topr]!='('&&flag;topr--){
flag=getresult(operators[topr]);
}
if(flag==0||topr==-1)
return 0;
topr--;
}
else if(ch=='*'||ch=='/'){
for(;topr>=0&&operators[topr]!='+'&&operators[topr]!='-'&&operators[topr]!='('&&flag;topr--){
flag=getresult(operators[topr]);
}
if(flag==0)
return 0;
operators[++topr]=ch;
}
else if(ch=='+'||ch=='-'){
for(;topr>=0&&operators[topr]!='('&&flag;topr--){
flag=getresult(operators[topr]);
}
if(flag==0)
return 0;
operators[++topr]=ch;
}
return 1;
}
int isoperand(char *data,int start)//判断是否为运算数
{
int i;
int flag=0;
for(i=start;data[i]&&data[i]!=' ';i++){
if(data[i]=='.'){
if(flag)
return 0;
if(i==start||data[i+1]=='\0'||data[i+1]==' ')//.不能出现在开头和末尾
return 0;
flag=1;
}
else if(data[i]=='-'&&i!=start)
return 0;
else if(!isdigit(data[i])){//不为数字
printf("%d %c p\n",i,data[i]);
return 0;
}
}
data[i]='\0';
return i;
}
int main()
{
int flag=1;//flag用来判断表达式合法否
char data[100];//读入原式
gets(data);
int length=strlen(data);
for(int i=0;i<=length&&data[i]!='\0'&&flag;i++){//此处length判断用于 location更新i后 过界
if(data[i]==' ')
continue;
else if(data[i]=='+'||data[i]=='-'||data[i]=='*'||data[i]=='/'||data[i]=='('||data[i]==')'){
flag=cal(data[i]);
}
else{
int location=isoperand(data,i);//判断是否为运算数 location为运算数末尾的后一个位置
if(location!=0){//为运算数
operand[++topd]=atof(data+i);
i=location;
}
else//不为运算数,也不为运算符
flag=0;
}
}
for(int i=topr;flag&&i>=0;i--)//剩余数据仍在栈中,待处理
flag=getresult(operators[i]);
if(flag==0||topd!=0)
printf("unlegal\n");
else
printf("%f\n",operand[0]);
return 0;
}
中序表达式的直接计算
最新推荐文章于 2024-03-05 23:19:47 发布