中綴和尾碼運算式求值演算法

來源:互聯網
上載者:User

運算式求值是程式設計語言編譯中的一個最基本問題,它的實現是堆棧應用的一個重要例子。程式中使用常用、直觀的“算符優先法”實現。

/*
 Copyright (c) 2006, 劉愛貴,  Aigui.LIU@ihep.ac.cn, Computing Center of IHEP, Beijing, China
 */

#include "stdafx.h"
#include "iostream.h"
#include "math.h"
#include "time.h"
#define  TRUE     1
#define  FALSE    0
#define  ERROR   -1
typedef int Status;
//用模板實現的鏈式結構堆棧類
template <class T>
class stack{
        private:
        struct link{
                T data;                 //結點資料域
                link *next;             //下一結點指標
                link(T Data,link* Next){//結構體建構函式
                data=Data;
                next=Next;
                }
        }*head;                    //堆棧頂指標
        public:
                stack();               //建構函式(初始化棧)
           ~stack();               //解構函式(銷毀棧)
            void  push(T Data);    //壓棧操作
                T gettop()const;       //取棧頂元素
                T pop();               //出棧操作
                T getvalue(int index); //返回棧底開始第INDEX個棧中值
                void  traverse(int n); //遍曆棧 N個數換行
                int   empty();         //判斷棧是否為空白,1是,0非
                int   sizeofstack();   //返回棧的大小
                void  clear();         //清空棧
};
//類模板成員函數的實現
template<class T> stack<T>::stack()//建構函式
{
        head=0;
}
template<class T> stack<T>::~stack()//解構函式
{
        link* cursor=head;
        while(head)
        {
                cursor=cursor->next;
                delete head;
                head=cursor;
        }
}
template<class T>void stack<T>::push(T Data)//壓棧操作
{
        head=new link(Data,head);
}
template<class T>T stack<T>::gettop()const//取棧頂元素
{
        return head->data;
}
template<class T>T stack<T>::pop()//出棧操作
{
        if(head==0)return 0;
        T result=head->data;
        link* oldhead=head;
        head=head->next;
        delete oldhead;
        return result;
}
template <class T>T stack<T>::getvalue(int index)//返回棧底開始第INDEX個棧中值
{
    link *cursor=head;
        int i=1;
        int stacklen=sizeofstack();
        if(index<=0||index>stacklen)return 0;
    while(i<=(stacklen-index))
        {
                cursor=cursor->next;
                i++;
        }
        return cursor->data;
}
template <class T> void stack<T>::traverse(int n)//遍曆棧
{
        link * cursor=head;
        int iEnterSign=1;//換行標識
        while(cursor)
        {
                cout<<cursor->data<<"  ";
                if(iEnterSign%n==0)cout<<endl;
                cursor=cursor->next;
                iEnterSign++;
        }
    if((iEnterSign-1)%n!=0)cout<<endl;
}
template <class T>int stack<T>::empty()         //判斷棧是否為空白,1是,0非
{
        return head==0?1:0;
}
template <class T>int stack<T>::sizeofstack()   //返回棧的大小
{
        int size=0;
        link *cursor=head;
        while(cursor)
        {
                cursor=cursor->next;
                size++;
        }
        return size;
}
template<class T> void stack<T>:: clear()         //清空棧
{
        link *cursor=head;
        while(cursor&&cursor->next)
        {
        cursor=cursor->next;
                delete head;
                head=cursor;
        }
}
int   Operator(char ch)
{
        if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#')
                return(TRUE);
        else
                return(FALSE);
}
char Precede(char ch1,char ch2)
{
        char ch;
        switch(ch1)
        {
        case '+':
        case '-':
                {
                        switch(ch2)
                        {
                        case '+':
                        case '-':
                        case ')':
                        case '#':
                                      ch='>';break;
                        case '*':
                        case '/':
                        case '(':
                                      ch='<';break;
                        }
                        break;
                }
        case '*':
        case '/':
                {
                        if(ch2=='(')
                                ch='<';
                        else
                                ch='>';
                        break;
                }
        case '(':
                {
                        if(ch2==')')
                                ch='=';
                        else
                                ch='<';
                        break;
                }
        case ')':
                {
                        ch='>';
                        break;
                }
        case '#':
                {
                        if(ch2=='#')
                                ch='=';
                        else
                            ch='<';
                        break;
                }
        }
        return(ch);
}
int calc(int x,char ch,int y)
{
   int z;
   switch(ch)
   {
    case '+': z=x+y; break;
    case '-': z=x-y; break;
    case '*': z=x*y; break;
    case '/': z=x/y; break;
   }
   return(z);
}
int postexpression(char *exp)
{
   stack<int> *opnd=new(stack<int>);
   char ch=*exp;
   int x=0,y,z,flag=FALSE;
   int result;
   while(ch!='#')
   {
           if(!Operator(ch))
           {
                   if(ch!=' ')
                   {
                         x=x*10+(int)(ch)-48;
                         flag=TRUE;
                   }
                   else
                   {
             if(flag)opnd->push(x);
                         x=0;
                         flag=FALSE;
                   }
           }
           else
           {
                   x=opnd->pop();
                   y=opnd->pop();
                   z=calc(y,ch,x);
                   opnd->push(z);
           }
           ch=*(++exp);
   }
   result=opnd->pop();
   return(result);
}
int middexpression(char *exp)
{
        stack<int> *opnd=new(stack<int>);
    stack<char> *optr=new(stack<char>);
    char ch=*exp;
    int x=0,y,z;
        int result;
        optr->push('#');
        while(ch!='#'||optr->gettop()!='#')
        {
                if(!Operator(ch))
                {

                   x=x*10+(int)(ch)-48;
                   if(Operator(*(exp+1)))
                   {
                         opnd->push(x);
                         x=0;
                   }
                   ch=*++exp;
                }
                else
                {
                    switch(Precede(optr->gettop(),ch))
                        {
                        case '<'://棧頂元素優先權低
                optr->push(ch);
                                ch=*++exp;
                                break;
                        case '='://脫括弧並接收下一字元
                                optr->pop();
                                ch=*++exp;
                                break;
                        case '>'://退棧並將運算結果入棧
                                x=opnd->pop();
                                y=opnd->pop();
                                z=calc(y,optr->pop(),x);
                                opnd->push(z);
                                x=0;
                                break;
                        }
                }
        }
        result=opnd->pop();
        return(result);
}
void main(void)//程式入口函數
{
        clock_t t1,t2,t3,t4;
        int i,n=9000;
        t1=clock();
        for(i=0;i<n;i++)
           postexpression("100 200 50 3 * - 13 8 - / +#");
       //postexpression("100 200 50 8 45 9 / - - + #");
           //postexpression("9 6 * 3 / 7 + 13 -#");
        t2=clock();
        printf("%10f/n",(t2-t1)/18.2/n);

        t3=clock();
        for(i=0;i<n;i++)
       middexpression("100+(200-50*3)/(13-8)#");
           //middexpression("100+(200-(50*(8-45/9)))#");
           //middexpression("9*6/3+7-13#");
        t4=clock();
        printf("%10f/n",(t4-t3)/18.2/n);

        printf("%10f",(t4-t3)/18.2/(t2-t1)*18.2);
        cin.get();
}//程式結束
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.