中序表达式的直接计算

//假设各运算符和运算数之间均有空格
//检验中缀表达式是否合法并计算结果
//用两个栈,一个存运算数,一个存运算符
#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;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值