博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

用栈对后缀表达式求值的算法(五种)

Posted on 2010-04-26 16:37  ccmfc  阅读(3293)  评论(0编辑  收藏  举报

  转载出处:http://blog.csdn.net/yrr6946996/archive/2008/10/22/3127072.aspx


 第一种

/* 此程序的功能是求出用户输入的整形表达式的值*/
/*输入的表达式请用#结尾,比如:2+3+5,应输入:2+3+5#。*/
#include <stdio.h>
#define   MAXSIZE 16

typedef struct{
      int data[MAXSIZE];
      int top;
      int base;
    }seqstack;   /* 顺序栈的定义*/
/*以下为函数声明*/
void InitStack(seqstack *);       
int Empty(seqstack *);
void Push(seqstack *, int );
int Pop(seqstack *);
int GetTop(seqstack *);
int Operate(int ,char ,int );
char Proceed(char ,char );
int In(char );
int EvalExpres(void);
 
/* 定义两个栈分别存放运算符和操作数*/
seqstack StackR,StackD;

/*主函数*/
int main()
{
int v;
char ch;
while(1)
{
    printf("end with #,for example 2+3+5 input:2+3+5#\n");
      printf("calculate:") ;
    v = EvalExpres();        
    printf("The result is:%d",v);
                 /*以下为程序控制*/        
   printf("\nInput 'q' to quit and ENTER run again:");
    do{  
         scanf("%c",&ch);     
      if(ch == 'q' || ch == 'Q')
     exit(0);
     }while(ch!='\n');
system("cls");
}
return 0;
}

void InitStack(seqstack *s)
{     s->top = 0;
      s->base = 0;
}   /* 初始化栈*/


int Empty(seqstack *s)
{   if(s->top == s->base)
             return 1;
     else
        return 0;
}    /* 判断栈是否为空*/


void Push(seqstack *s, int x)
{   
    if(s->top == MAXSIZE)
         {    printf("OVER FLOW!\n");
              exit(0);
         }
    else
         {    s->data[s->top] = x;
              s->top++;
         }    
}    /* 进栈 */

int Pop(seqstack *s)
{    int e;
     if(Empty(s))
        {   printf("Under flow!\n");
             return 0;
        }   /* 下溢*/
     else
        {   s->top--;
          e = s->data[s->top];
            return e;
        }
} /* 出栈*/

int GetTop(seqstack *s)    /*取栈顶元素*/
{  
    if(Empty(s))
        {   printf("Under flow!\n");
             return 0;
        }
   else
      return s->data[s->top-1];     
}

int EvalExpres(void)    /* 表达式求解函数*/
{
     int a,b,i=0,s=0;
     char c[80],r;
     InitStack(&StackR);
     Push(&StackR,'#');
     InitStack(&StackD);
     printf(" end with #");
     gets(c);
     while(c[i]!='#' || GetTop(&StackR)!='#')
      {     
         if(!In(c[i]))   /* 判断读入的字符不是运算符 是则进栈*/
           { if(c[i] >= '0' && c[i] <= '9')
                {
                  s += c[i]-'0';     
                  while(!In(c[++i]))    /*此处实现的功能为当输入的数字为多位数时*/
                  { s*=10;
                    s += c[i]-'0';
                  }
                Push(&StackD,s+'0');
                  s = 0;
                }
             else
              {
                printf("wrong!\n");
                  return 0;
              }           
           }
      else        
         switch(Proceed(GetTop(&StackR),c[i])) /* 此函数用来比较读取的运算符和栈顶运算符的优先级*/
           {
               case '<':   /* 栈顶的元素优先级高*/
                 Push(&StackR,c[i]);
                    i++;
                  break;
               case '=':   /* 遇到匹配的小括号时则去掉他*/
                 Pop(&StackR);
                 i++;
                  break;
               case '>': /* 栈顶的优先级低则出栈并将结果写入栈内*/
                 r = Pop(&StackR);
                 a = Pop(&StackD)-'0';
                 b = Pop(&StackD)-'0';
                 Push(&StackD,Operate(a,r,b)) ;
                  break;               
           }
      }
return (GetTop(&StackD)-'0');   /* 返回运算结果*/
}

 

int In(char c)         /*问题2:解决In函数问题:判断C是否为运算符是返回1否则返回0*/
{
   char ch[7]={'+','-','*','/','#','(',')'};
   int i;
   for(i = 0; i < 7; i++)
          if(c == ch[i])
             return 1;
            
             return 0;           
}

char Proceed(char op,char c) /*op为栈顶元素,c为当前读入的运算符,比较二者的优先级*/
{                                                    /*问题1:解决Proceed函数*/
      char ch;             
      if(op=='(' && c==')' || op=='#' && c=='#' )
          ch = '=';
else
      if(op=='+' || op=='-')     /*栈顶元素为‘+’或‘-’的时候*/
        switch(c)
           {
              case '+':
              case '-':
              case ')':
              case '#': ch = '>'; break;
              case '*':
              case '/':
              case '(': ch = '<';
           }
else
      if(op=='*' || op=='/')    /*栈顶元素为‘*’或‘/’的时候*/
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':    
             case ')':
             case '#':    ch = '>'; break;
             case '(':    ch = '<';
           }
else
      if(op=='(')             /*栈顶元素为‘(’的时候*/
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':
             case '(': ch = '<'; break;
             case '#':   printf("Error!\n"); exit(0);
           }
else
      if(op==')')     /*栈顶元素为‘)’的时候*/
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':
             case '#': ch = '>'; break;
             case '(': printf("Error!\n"); exit(0);
           }
else
      if(op=='#')              /*栈顶元素为‘#’的时候*/
        switch(c)
           {
             case '+':
             case '-':
             case '*':
             case '/':
             case '(': ch = '<'; break;
             case ')':   printf("Error!\n"); exit(0);
           }
return ch;                              
}          
/*   问题3:解决Operate函数*/
int Operate(int a,char r,int b) /*返回由aRb的值 */
{
   int s;
   int d1 = a;
   int d2 = b; /*把字符ab变为对应数字*/
   switch(r)
      {
         case '+': s = d1+d2; break;
         case '-': s = d2-d1; break;
         case '*': s = d1*d2; break;
         case '/': s = d2/d1;   
      }
return (s+'0');   
}


第二种

#include <stdio.h>
#include <malloc.h>

#define MaxSize 50

void trans(char *exp,char *postexp)
{
    struct
    {
        char data[MaxSize];
        int top;
    } op;
    int i=0;
    op.top=-1;
    while(*exp!='\0')
    {
        switch(*exp)
        {
            case '(':
                op.top++;op.data[op.top]=*exp;
                exp++;break;
            case ')':
                while(op.data[op.top]!='(')
                {
                    postexp[i++]=op.data[op.top];
                    op.top--;
                }           
                op.top--;exp++;break;   
            case '+':
            case '-':
                while(op.top!=-1&&op.data[op.top]!='(')
                {
                    postexp[i++]=op.data[op.top];
                    op.top--;
                }       
                op.top++;op.data[op.top]=*exp;exp++;break;
            case '*':
            case '/':
                while(op.data[op.top]=='*'||op.data[op.top]=='/')
                {
                    postexp[i++]=op.data[op.top];
                    op.top--;
                }
                op.top++;op.data[op.top]=*exp;exp++;break;
            case ' ':break;
            default:
                while(*exp>='0'&&*exp<='9')
                {
                    postexp[i++]=*exp;
                    exp++;
                }    
                postexp[i++]='#';
        }   
    }  
    while(op.top!=-1)
    {
        postexp[i++]=op.data[op.top];
        op.top--;
    }  
    postexp[i]='\0';
}  

float compvalue(char *postexp)
{
    struct
    {
        float data[MaxSize];
        int top;
    } st;
    float a,b,c,d;
    st.top=-1;
    while(*postexp!='\0')
    {
        switch(*postexp)
        {
            case '+':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                c=b+a;
                st.top++;
                st.data[st.top]=c;
                break;
            case '-':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                c=b-a;
                st.top++;
                st.data[st.top]=c;
                break;
            case '*':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                c=b*a;
                st.top++;
                st.data[st.top]=c;
                break;
            case '/':
                a=st.data[st.top];
                st.top--;
                b=st.data[st.top];
                st.top--;
                if(a!=0)
                {
                    c=b/a;
                    st.top++;
                    st.data[st.top]=c;
                }   
                else
                {
                    printf("\n\t除零错误!\n");
                    exit(0);
                }   
                break;
            default:
                d=0;
                while(*postexp>='0'&&*postexp<='9')
                {
                    d=10*d+*postexp-'0';
                    postexp++;
                }   
                st.top++;
                st.data[st.top]=d;
                break;
        }   
        postexp++;
    }   
    return st.data[st.top];
}  

int main()
{
    char exp[MaxSize],postexp[MaxSize];
    while(scanf("%s",&exp)!=EOF)
    {
        trans(exp,postexp);
        printf("zhongzhuibiaodashi:  %s\n",exp);
        printf("houzuibiaodashi:     %s\n",postexp);
        printf("zhi:                 %g\n",compvalue(postexp));
    }   
    return 0;
}  


第三种

#include<stdio.h>
#include<stdlib.h>
#define add  43
#define subs 45
#define mult 42
#define div 47
#define MAXSIZE 100

typedef struct
{
    int data[MAXSIZE];
    int top;
}seqstack;
seqstack *s;

 seqstack *Init()  /*栈的初始化*/
{
 seqstack *s;
 s=(seqstack *)malloc(sizeof(seqstack));
 if(!s)
    {printf("FULL!");
     return NULL;
     }
  else
    {s->top=-1;
     return s;
     }
 }


 int Empty(seqstack *s)  /*栈空的判断*/
 {if(s->top==-1) return 1;
   else return 0;
  }

 int Push(seqstack *s,int x) /*入栈*/
 {if(s->top==MAXSIZE-1) return 0;
   else
       {s->top++;
        s->data[s->top]=x;
        return 1;
        }
  }

  int Pop(seqstack *s,int *x) /*出栈的算法*/
  {if (Empty(s))  return 0;
   else
      {*x=s->data[s->top];
       s->top--;
       return 1;
       }
   }


   int Top(seqstack *s)       /*取栈顶元素*/
   {if(Empty(s)) return 0;
     else return s->data[s->top];
    }

   int eval(char t,int a1,int a2)
   {switch(t)
         {case add:return(a1+a2);
          case subs:return(a1-a2);
          case mult:return(a1*a2);
          case div:return(a1/a2);
          }
    }

    void main()
    {char c;
     int op1,op2,temp,c1;
     s=Init();
     printf("Input:(end with #)\n");
     while((c=getchar())!='#')
       {if(c=='')continue;
        if(c>47&&c<58)
          {putchar(c);
           c1=c-48;
           Push(s,c1);
           }
        else if(c==add||c==subs||c==mult||c==div)
             {putchar(c);
              Pop(s,&op1);
              Pop(s,&op2);
              temp=eval(c,op2,op1);
              Push(s,temp);
              }
         else printf("It's wrong!\n");
        }
     Pop(s,&op1);
     printf("=%d\n",op1);
     getch();
    }

 

第四种

#include<stdio.h>
#include<stdlib.h>
#define add  43
#define subs 45
#define mult 42
#define div 47
#define MAXSIZE 100

typedef struct
{
    int data[MAXSIZE];
    int top;
}STKzone;
typedef STKzone *STK;
typedef enum{ture=1,false=0} bool;
typedef enum{ok,error} status;
STKzone expSTKzone;
STK expSTK;

STK initSTK(STKzone *stkzone) /*栈的初始化*/
{STK p;
p=stkzone;
p->top=0;
}

status push(int *term,STK pstk) /*入栈*//*term前可以没有*,同时将第28、71、81行稍作修改即可 */
{if(pstk->top==MAXSIZE) return error;
 pstk->data[pstk->top]=*term;
 pstk->top++;
 return ok;
 }

 bool emptySTK(STK pstk)   /*栈空的判断*/
 {return (pstk->top==0);
 }

 status pop(int *pdata,STK pstk)  /*出栈的算法*/
 {if (emptySTK(pstk)) return error;
  (pstk->top)--;
  *pdata=pstk->data[pstk->top];
  return ok;
  }


  void synerror()
  {printf("\nyu fa cuo wu!");


  }

  int eval(char tag,int a1,int a2)
  {switch(tag)
         {case add:return(a1+a2);
          case subs:return(a1-a2);
          case mult:return(a1*a2);
          case div:return(a1/a2);
          }
  }


  main()
  { char c;
     int op1,op2,temp,c1;
     expSTK=initSTK(&expSTKzone);
     printf("Input:\n");
     while((c=getchar())!='\n')
       {if(c=='')continue;
        if(c>47&&c<58)
          {putchar(c);
           c1=c-48;
           if(push(&c1,expSTK)==error)
           {printf("\n too long!\n");

            }
           }
        else if(c==add||c==subs||c==mult||c==div)
            {putchar(c);
             if(pop(&op1,expSTK)==error)synerror();
             if(pop(&op2,expSTK)==error)synerror();
             temp=eval(c,op2,op1);
             push(&temp,expSTK);
             }
         else synerror();
        }
     if(pop(&op1,expSTK)==error) synerror();
     if(!(emptySTK(expSTK))) synerror();
     printf("=%d\n",op1);
     getch();
    }

第五种

#include<stdio.h>
#include<stdlib.h>
#define add  43
#define subs 45
#define mult 42
#define div 47
#define MAXSIZE 100

typedef struct
{
    int stkdata[MAXSIZE];
    int top;
}stack;

int init_stack(stack *s)
{ s=(stack *)malloc(sizeof(stack));
 if(!s)
   {printf("FULL!\n");
    return 0;
    }
 else
    {s->top=-1;
     return 1;
     }
}

int push(stack *s,int x)
{ if(s->top==MAXSIZE-1)
    { printf("over flow\n");
      return 0;
    }
   else
    {s->top++;
     s->stkdata[s->top]=x;
     return 1;
    }
}

char pop(stack *s)

{   char e;
    if(s->top==-1)
    {
        printf("under flow \n");
        return 0;
    }
    e=s->stkdata[(s->top)--];
    return e;
}

void main()
{
    stack *s1;
    int length,i,num1,num2,result,sum;
    char s[100];
    init_stack(s1);
    printf("please input \n");
    printf("warning:must less than 100\n");
    gets(s);
    length=strlen(s);
    for(i=0;i<=length-1;i++)
     {  if(s[i]>='1'&&s[i]<='9')
         push(s1,s[i]-48);
            else
            {   num1=pop(s1);
                num2=pop(s1);
                switch(s[i])
                {
                  case add: {sum=num1+num2;
                             push(s1,sum);
                             break;
                             }
                  case subs:{sum=num2-num1;
                             push(s1,sum);
                             break;
                             }
                    case div:{sum=num2/num1;
                              push(s1,sum);
                              break;
                             }

                    case mult:{sum=num1*num2;
                               push(s1,sum);
                               break;
                               }
                }
            }
        }
        result=s1->stkdata[s1->top];
        printf("result is %d\n",result);
        getch();
    }

在研究表达式。。。无意中看到这。。。太精典了。。。不得不转啊。。。