1. 程式人生 > >資料結構中用棧實現表示式求值(c語言實現)

資料結構中用棧實現表示式求值(c語言實現)

/*
該程式完成了個位數的各類表示式求值
運用了資料結構中的棧及對棧操作的各類函式,操作全用指標完成
如輸入 2+3*(3+3*1)#  輸出結果為 20
經測試個位數的表示式運算結果均正確
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STACK_INIT_SIZE 1000
typedef struct             //建造一個空棧
{
 char *base;
 char *top;
 int stacksize;
}SqStack;
int InitStack(SqStack *s)       //給棧分配空間,初始化棧
{
    (*s).base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
    if(!((*s).base))
        exit(0);
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;
    return 1;
}
int Push(SqStack *s,char *ch)    //把接收到的第一個元素壓入棧
{
  if(s->top-s->base>=STACK_INIT_SIZE)
    return 0;
     *((*s).top)=*ch;
    (*s).top++;
    return 1;
}
void  Pop(SqStack *s,char *ch){      //刪除棧頂元素
    s->top--;
*ch=*(s->top);
}
char* Gettop(SqStack *s)            //得到棧頂元素
{
 if(s->top!=s->base)


    return (*s).top-1;
}
int In(char *c)          //判斷吸收的資料是不是字元
{
    switch(*c)
    {
    case'+':
    case'-':
    case'*':
    case'/':
    case'(':
    case')':
    case'#':return 1;
    default:return 0;
    }
}
char *Operate(char *a,char *theta,char *b)   //彈出棧的元素進行運算
{
   char *c;
   *a=*a-48;
   *b=*b-48;
   c=(char *)malloc(sizeof(char));
    switch(*theta)
    {
    case'+':
        *c=*a+*b+48;
        break;
    case'-':
        *c=*a-*b+48;
        break;
    case'*':
        *c=(*a)*(*b)+48;
        break;
    case'/':*c=(*a)/(*b)+48;break;
    }
    return c;
}
char Precede(char *ch1,char *ch2)     //判斷運算子的先後順序
{
     if(*ch1=='+')
     {
     if(*ch2=='+')return '>';
     if(*ch2=='-')return '>';
     if(*ch2=='*')return '<';
     if(*ch2=='/')return '<';
     if(*ch2=='(')return '<';
     if(*ch2==')')return '>';
     if(*ch2=='#')return '>';
     }
     if(*ch1=='-')
     {
     if(*ch2=='+')return '>';
     if(*ch2=='-')return '>';
     if(*ch2=='*')return '<';
     if(*ch2=='/')return '<';
     if(*ch2=='(')return '<';
     if(*ch2==')')return '>';
     if(*ch2=='#')return '>';
     }
     if(*ch1=='*')
     {
     if(*ch2=='+')return '>';
     if(*ch2=='-')return '>';
     if(*ch2=='*')return '>';
     if(*ch2=='/')return '>';
     if(*ch2=='(')return '<';
     if(*ch2==')')return '>';
     if(*ch2=='#')return '>';
     }
          if(*ch1=='/')
     {
     if(*ch2=='+')return '>';
     if(*ch2=='-')return '>';
     if(*ch2=='*')return '>';
     if(*ch2=='/')return '>';
     if(*ch2=='(')return '<';
     if(*ch2==')')return '>';
     if(*ch2=='#')return '>';
     }
          if(*ch1=='(')
     {
     if(*ch2=='+')return '<';
     if(*ch2=='-')return '<';
     if(*ch2=='*')return '<';
     if(*ch2=='/')return '<';
     if(*ch2=='(')return '<';
     if(*ch2==')')return '=';
     }
          if(*ch1==')')
     {
     if(*ch2=='+')return '>';
     if(*ch2=='-')return '>';
     if(*ch2=='*')return '>';
     if(*ch2=='/')return '>';
     if(*ch2==')')return '>';
     if(*ch2=='#')return '>';
     }
     if(*ch1=='#')
     {
     if(*ch2=='+')return '<';
     if(*ch2=='-')return '<';
     if(*ch2=='*')return '<';
     if(*ch2=='/')return '<';
     if(*ch2=='(')return '<';
     if(*ch2=='#')return '=';
     }
}
int main()
{
    char *theta,*ch,*x,*c;
    char *a,*b;
    SqStack OPND;
    SqStack OPTR;
    InitStack(&OPND);    //創作一個存數字的棧
    InitStack(&OPTR);     //創作一個存運算子和括號的棧
    c=(char *)malloc(sizeof(char));   //分配記憶體
    ch=(char *)malloc(sizeof(char));
    x=(char *)malloc(sizeof(char));
    theta=(char *)malloc(sizeof(char));
    a=(char *)malloc(sizeof(char));
    b=(char *)malloc(sizeof(char));
    *c='#';
    Push(&OPTR,c);
    printf("請輸入以#結尾的表示式\n");
    *ch=getchar();
    while((*ch)!='#'||(*(Gettop(&OPTR)))!='#'){  //運算結束停止條件
        if(!In(ch)){
            Push(&OPND,ch);
            printf("壓入OPND棧  %d\n",*ch);
            *ch=getchar();
        }
        else
            switch(Precede(Gettop(&OPTR),ch))     //通過比較接收的字元來進行運算
        {
         case'<':
         Push(&OPTR,ch);
         printf("壓入OPTR棧   %c\n",*ch);
         *ch=getchar();
         break;
         case'>':
         Pop(&OPTR,theta);
         printf("壓入前%d %d\n",*b,*a);
         Pop(&OPND,b);
         Pop(&OPND,a);
         printf("刪除後OPND的頭%d %d\n",*b,*a);
         Push(&OPND,Operate(a,theta,b));
         printf("運算後 %d\n",*theta);
         break;
         case'=':
            Pop(&OPTR,x);
            *ch=getchar();
            break;}
    }
    printf("\n\n\n");
    printf("運算結果= %d",(*Gettop(&OPND)-48));
}