顺序栈实现表达式求值

 大一的时候老师叫用c写计算器
能处理多个括号嵌套的
我33行搞定
其实是不会写
只好偷偷写个vbs脚本
由vbs把值算出来再写入文件再读取

现在我会用栈了
补上这迟来的作业
应龙哥怕是看不到了
奶奶的
那个xx的计算器程序还是我替他写的
应龙哥 你怎么可以让他的vc成绩比我还高呢
从此培养了我的厌分习惯 
我好恨

/***************************************************************************
*   Copyright (C) 2008 by root   *
使用顺序栈实现的表达式求解
**************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LIST_INIT_SIZE 88
#define LIST_INCREMENT 4

typedef  double ElemTypeOpnd;
typedef char ElemTypeOptr;

typedef struct
{
    ElemTypeOptr *top;
    int stacksize;

    ElemTypeOptr *base;
} SqOplnd;

typedef struct
{
    ElemTypeOpnd *top;
    int stacksize;
    ElemTypeOpnd *base;
}SqOpnd;

void Init_SqOpnd ( SqOpnd *L );
void PushOpnd ( SqOpnd *L,ElemTypeOpnd e );
int PopOpnd ( SqOpnd *L );
ElemTypeOpnd GetOpndTop ( SqOpnd L );
int IsOpndNULL ( SqOpnd L );
void DestoryOpnd ( SqOpnd *L );

void Init_SqOplnd ( SqOplnd *L );
void PushOplnd ( SqOplnd *L,ElemTypeOptr e );
int PopOplnd ( SqOplnd *L );
ElemTypeOptr GetOplndTop ( SqOplnd L );
int IsOplndNULL ( SqOplnd L );
void DestoryOplnd ( SqOplnd *L );

int In ( char e );
int ShowPower ( char a );
int IsRight ( char *a );
int Precede ( char a,char b );
double cal ( char exp[] );

double cal ( char exp[] )
{
    char *p=exp;
    SqOpnd S;
    Init_SqOpnd ( &S );
    double a,b;
    while ( *p!='/0' )
    {
        if ( !In ( *p ) &&*p!='|' )
        {
            double a=strtod ( p,NULL );
            PushOpnd ( &S,a );
            while ( *p++!='|' );
        }
        if(*p=='|')
        {
            p++;
        }
        if(In(*p))
        {
            b=GetOpndTop(S);
            PopOpnd(&S);
            a=GetOpndTop(S);
            PopOpnd(&S);
            if(*p=='+')
                a=a+b;
            if(*p=='-')
                a=a-b;
            if(*p=='*')
                a=a*b;
            if(*p=='/')
                a=a/b;
            p++;
            PushOpnd(&S,a);
        }
    }
    a=GetOpndTop(S);
   
    DestoryOpnd ( &S );
    return a;

}

void transform ( char suffix[],char x[] )
{
    char exp[80]="";

    strncat ( exp,x,strlen ( x ) );
    strncat ( exp,"#",1 );
    //printf("%s/n",exp);
    SqOplnd S;
    Init_SqOplnd ( &S );
    PushOplnd ( &S,'#' );
    char *p;
    char q;
    p=exp;

    while ( *p!='/0' )
    {
        if ( !In ( *p ) )
        {
            strncat ( suffix,p,1 );
            p++;
        }
        else
        {
            char *m=suffix;
            while ( *m++!='/0' );
            *m--;
            if ( *p!='('&&!In ( *m ) )
                strncat ( suffix,"|",1 );
            switch ( *p )
            {
                case '#':

                    while ( GetOplndTop ( S ) !='#' )
                    {

                        q=GetOplndTop ( S );
                        strncat ( suffix,&q,1 );
                        PopOplnd ( &S );

                    }
                    PopOplnd ( &S );
                    break;
                case '(':
                    PushOplnd ( &S,*p );
                    break;
                case ')':
                    while ( GetOplndTop ( S ) !='(' )
                    {
                        q=GetOplndTop ( S );
                        strncat ( suffix,&q,1 );
                        PopOplnd ( &S );
                    }
                    PopOplnd ( &S );
                    break;
                case '*':
                case '/':
                case '+':
                case '-':
                    //printf("this is /t %c/n",*p);

                    while ( !Precede ( *p,GetOplndTop ( S ) ) )
                    {
                        q=GetOplndTop ( S );
                        PopOplnd ( &S );
                        strncat ( suffix,&q,1 );
                    }


                    PushOplnd ( &S,*p );

                    break;
                default:break;
            }
            p++;
        }
    }
    DestoryOplnd ( &S );




}

int Precede ( char a,char b )
{
    if ( ShowPower ( a ) >ShowPower ( b ) )
    {

        return 1;
    }
    else
        return 0;
}

int IsRight ( char *a )
{
    //printf ( "%s/n",a );
    SqOplnd string;
    Init_SqOplnd ( &string );
    while ( *a!='/0' )
    {
        if ( *a=='(' )
            PushOplnd ( &string,*a );
        if ( *a==')' )
        {
            if ( !PopOplnd ( &string ) )
            {
                DestoryOplnd ( &string );
                return 0;
            }
        }
        a++;
    }
    if ( IsOplndNULL ( string ) )
    {
        DestoryOplnd ( &string );
        return 1;
    }
    else
    {
        DestoryOplnd ( &string );
        return 0;
    }
}

int ShowPower ( char a )
{
    if ( a=='*'||a=='/' )
    {
        return 2;
    }
    if ( a=='+'||a=='-' )
    {
        return 1;
    }
    if ( a=='(' )
    {
        return 0;
    }
    if ( a=='#' )
    {
        return -1;
    }
}

int In ( char e )
{
    if ( e=='#'||e=='+'||e=='-'||e=='*'||e=='/'||e=='('||e==')' )
        return 1;
    return 0;
}

int IsOplndNULL ( SqOplnd L )
{
    if ( L.top==L.base )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

ElemTypeOptr GetOplndTop ( SqOplnd L )
{
    if ( L.top==L.base )
    {
        printf ( "stack is null/n" );
        return;
    }

    return ( * ( L.top-1 ) );
}

int PopOplnd ( SqOplnd *L )
{
    if ( ( *L ).top== ( *L ).base )
    {
        printf ( "stack is null/n" );
        return 0;
    }
    ( *L ).top--;
    return 1;
}

void PushOplnd ( SqOplnd *L,ElemTypeOptr e )
{
    int lenth= ( *L ).top- ( *L ).base;
    ElemTypeOptr *newbase;
    if ( lenth>= ( ( *L ).stacksize-1 ) )
    {

        newbase= ( ElemTypeOptr* ) realloc ( ( ( *L ).base ), ( ( ( *L ).stacksize+LIST_INCREMENT ) *sizeof ( ElemTypeOptr ) ) );
        if ( !newbase )
            exit ( 1 );
        ( *L ).base=newbase;
        ( *L ).top= ( *L ).base+lenth;
        ( *L ).stacksize+=LIST_INCREMENT;
        //printf("new memory add/n");
    }
    * ( ( *L ).top ) =e;
    ( *L ).top++;
}

void Init_SqOplnd ( SqOplnd *L )
{
    ( *L ).base=malloc ( LIST_INIT_SIZE*sizeof ( ElemTypeOptr ) );
    if ( ! ( *L ).base )
        exit ( 1 );
    ( *L ).top= ( *L ).base;

    ( *L ).stacksize=LIST_INIT_SIZE;
}

void DestoryOplnd ( SqOplnd *L )
{

    free ( ( *L ).base );
    ( *L ).base=NULL;
    ( *L ).top= ( *L ).base;
    ( *L ).stacksize=0;
}

int IsOpndNULL ( SqOpnd L )
{
    if ( L.top==L.base )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

ElemTypeOpnd GetOpndTop ( SqOpnd L )
{
    if ( L.top==L.base )
    {
        printf ( "stack is null/n" );
        return;
    }

    return ( * ( L.top-1 ) );
}


int PopOpnd ( SqOpnd *L )
{
    if ( ( *L ).top== ( *L ).base )
    {
        return 0;
    }
    ( *L ).top--;
    return 1;
}

void PushOpnd ( SqOpnd *L,ElemTypeOpnd e )
{
    int lenth= ( *L ).top- ( *L ).base;
    ElemTypeOpnd *newbase;
    if ( lenth>= ( ( *L ).stacksize-2 ) )
    {

        newbase= ( ElemTypeOpnd* ) realloc ( ( ( *L ).base ), ( ( ( *L ).stacksize+LIST_INCREMENT ) *sizeof ( ElemTypeOpnd ) ) );
        if ( !newbase )
            exit ( 1 );
        ( *L ).base=newbase;
        ( *L ).top= ( *L ).base+lenth;
        ( *L ).stacksize+=LIST_INCREMENT;
        //printf("new memory add/n");
    }
    * ( ( *L ).top ) =e;
    ( *L ).top++;
}

void Init_SqOpnd ( SqOpnd *L )
{
    ( *L ).base=malloc ( LIST_INIT_SIZE*sizeof ( ElemTypeOpnd ) );
    if ( ! ( *L ).base )
        exit ( 1 );
    ( *L ).top= ( *L ).base;

    ( *L ).stacksize=LIST_INIT_SIZE;
}
void DestoryOpnd ( SqOpnd *L )
{
    free ( ( *L ).base );
    ( *L ).base=NULL;
    ( *L ).top= ( *L ).base;
    ( *L ).stacksize=0;
}



int main ( int argc, char *argv[] )
{
    char input[81];
    begin:
            printf ( "请输入计算表达式 80字以内/n" );
    scanf("%s",input);
    getchar();
    printf("表达式为%s/t",input);
    if(IsRight(input))
    {
        printf("括号正确/n");
    }
    else
    {
        printf("括号匹配错误 请重新输入/n");
        goto begin;
    }
   
    char a[150]="";
    transform(a,input);
    printf("后缀表达式/t%s/n",a);
    double  yeah=cal(a);
    printf ( "结果:/t%g/n",yeah);
    printf("继续 c  退出 anykey/n");
    if(toupper(getchar())=='C')
    {
        getchar();
        goto begin;
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值