Expression Evaluation(表达式求值)

20080927

数据结构中栈的应用。

#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
#include<bios.h>
typedef struct stack
{
    union
    {
        float value;
        char sign;
    }data;
    struct stack *down;
}ST;
void finish(ST *topv);
void c2(ST **ptopv,ST **ptops);
void error();
ST *compute(ST *a,char sign,ST *b);
void push(ST **ptop,ST *in);
ST *pop(ST **ptop);
char *read(ST *r,char *class,char *ch);
char convert(char sign);
void rsgs(char *p,char max);
int rsgc();
void option(ST **ptopv,ST **ptops,ST *cu,char *pclass);
void main()
{
    ST *topv=0,*tops=0,*cu;
    char ch[71],class,*p=ch;
    printf("\n Expression Evaluation V20080928 by roundsheep");
    printf("\n\n Max String:70");
    printf("\n\n Max Significant Digits:6");
    printf("\n\n Max Decimal Digits:5");
    printf("\n\n Can only use the digit or +-*/()");
    printf("\n\n Please input expression:\n\n ");
    rsgs(ch,70);
    while(1)
    {
        cu=(ST *)malloc(sizeof(ST));
        p=read(cu,&class,p);
        if(p==0||cu==0)error();
        option(&topv,&tops,cu,&class);
        if(*p==0)
        {
            while(tops!=0)c2(&topv,&tops);
            if(tops==0&&topv->down==0)finish(topv);
            else error();
        }
    }
}

ST *compute(ST *a,char sign,ST *b)
{
    switch(sign)
    {
        case '+':a->data.value+=b->data.value;break;
        case '-':a->data.value-=b->data.value;break;
        case '*':a->data.value*=b->data.value;break;
        case '/':a->data.value/=b->data.value;
    }
    return a;
}
void push(ST **ptop,ST *in)
{
    in->down=*ptop;
    *ptop=in;
}
ST *pop(ST **ptop)
{
    ST *t;
    if(*ptop==0)return 0;
    t=*ptop;
    *ptop=(*ptop)->down;
    return t;
}
char *read(ST *r,char *pclass,char *ch)
{
    float b;
    switch(*ch)
    {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':
        case ')':
            r->data.sign=*ch;
            *pclass='s';
            return ch+1;
    }
    if(!isdigit(*ch))return 0;
    *pclass='v';
    for(r->data.value=0;isdigit(*ch);ch++)
    {
        r->data.value*=10;
        r->data.value+=*ch-48;
    }
    if(*ch!='.')return ch;
    ch++;
    if(!isdigit(*ch))return 0;
    for(b=10;isdigit(*ch)&&b<10e6;ch++,b*=10)
    r->data.value+=(*ch-48)/b;
    return ch;
}
char convert(char sign)
{
    char c;
    switch(sign)
    {
        case '+':c=0;break;
        case '-':c=1;break;
        case '*':c=2;break;
        case '/':c=3;break;
        case '(':c=4;break;
        case ')':c=5;
    }
    return c;
}
void error()
{
    printf("\n\n Error!");
    rsgc();
    exit(0);
}
void c2(ST **ptopv,ST **ptops)
{
    ST *com1,*com2;
    com2=pop(ptopv);
    com1=pop(ptopv);
    if(com1==0)error();
    com1=compute(com1,pop(ptops)->data.sign,com2);
    push(ptopv,com1);
}
void finish(ST *topv)
{
    printf("\n\n Result:\n\n %.3f",topv->data.value);
    rsgc();
    exit(0);
}
int rsgc()
{
    int c=0,key;
    key=bioskey(0);
    switch(key)
    {
        case 11779:c=6;exit(0);/* quit */
        case 3592:c=5;break;/* backspace */
        case 7181:c=10;break;/* enter */
        case 18432:c=1;break;/* up down left right */
        case 20480:c=2;break;
        case 19200:c=3;break;
        case 19712:c=4;break;
    }
    if(c)return c;
    return key&0xff;
}
void rsgs(char *p,char max)
{
    char s=max;
    do
    {
        do
        {
        *p=rsgc();
      }while(*p==5&&s==max||*p!=10&&*p!=5&&s==0);
      if(*p==5)
      {
        printf("\b \b");
        s+=2;
        p-=2;
      }
        else if(*p==10){*p=0;return;}
        else if(*p>=33&&*p<=126)putchar(*p);
        else putchar(' ');
        p++;
    }while(s--);
    *--p=0;
}
void option(ST **ptopv,ST **ptops,ST *cu,char *pclass)
{
    char t,cp[6][6]=
    {
        {1,1,-1,-1,-1,1},
        {1,1,-1,-1,-1,1},
        {1,1,1,1,-1,1},
        {1,1,1,1,-1,1},
        {-1,-1,-1,-1,-1,0},
        {-1,-1,-1,-1,-2,1}
    };
    if(*pclass=='v'){push(ptopv,cu);return;}
    if(*ptops==0){push(ptops,cu);return;}
    t=cp[convert((*ptops)->data.sign)][convert(cu->data.sign)];
    switch(t)
    {
        case -2:error();
        case 0:pop(ptops);break;
        case -1:push(ptops,cu);break;
        case 1:{c2(ptopv,ptops);option(ptopv,ptops,cu,pclass);}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值