1. 程式人生 > 實用技巧 >棧——表示式求值

棧——表示式求值

//"SqStack.h"
#include<iostream>
using namespace std;

#define SElemType_int int
#define SElemType_char char
#define MAXSIZE 100

typedef struct{
    SElemType_int *base;
    SElemType_int *top;
    int stacksize;
}SqStack_int;

typedef struct{
    SElemType_char *base;
    SElemType_char *top;
    
int stacksize; }SqStack_char; string InitStack(SqStack_int &S){ S.base = new SElemType_int[MAXSIZE]; S.top = S.base; S.stacksize=MAXSIZE; return "OK"; } string InitStack(SqStack_char &S){ S.base = new SElemType_char[MAXSIZE]; S.top = S.base; S.stacksize=MAXSIZE;
return "OK"; } string Push(SqStack_int &S,SElemType_int e){ if(S.top-S.base == S.stacksize) return "ERROR"; *S.top=e; S.top++; return "OK"; } string Push(SqStack_char &S,SElemType_char e){ if(S.top-S.base == S.stacksize) return "ERROR"; *S.top=e; S.top++; return
"OK"; } string pop(SqStack_int &S,SElemType_int &e){ if(S.base == S.top) return "ERROE"; S.top--; e = *S.top; return "OK"; } string pop(SqStack_char &S,SElemType_char &e){ if(S.base == S.top) return "ERROE"; S.top--; e = *S.top; return "OK"; } SElemType_int GetTop(SqStack_int S){ if(S.top != S.base){ return *(S.top-1); } } SElemType_char GetTop(SqStack_char S){ if(S.top != S.base){ return *(S.top-1); } } int StackEmpty(SqStack_char S){ if(S.top == S.base) return 1; return 0; } int StackEmpty(SqStack_int S){ if(S.top == S.base) return 1; return 0; }

#include<iostream>
#include"SqStack.h"
using namespace std;

/*
    表示式求值
*/


char Precede(char a,char b){  //比較行符間順序 ,a在前,b在後
    switch (a)
    {
    case '+':  
    case '-':              //棧底元素為'+'或'-'時
        switch (b)
        {
        case '+':
        case '-':
        case ')':
        case '#':
            return '>';
            break;
        case '*':
        case '/':
        case '(':
            return '<';
            break;      
        }
        break;

    case '*':
    case '/':
        switch (b)
        {
        case '+':
        case '-':
        case '*':
        case '/':
        case ')':
        case '#':
            return '>';
            break;
        case '(':
            return '<';
            break;      
        }
        break;

    case '(':
        switch (b)
        {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':
            return '<';
            break;
        case ')':
            return '=';
            break;      
        }
        break;     

    case ')':
        switch (b)
        {
        case '+':
        case '-':
        case '*':
        case '/':
        case ')':
        case '#':
            return '>';
            break;    
        }
        break;     
    
    case '#':
        switch (b)
        {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':
            return '<';
            break;
        case '#':
            return '=';
            break;      
        }
        break; 
    }
}

int Operate(int a,char Op,int b){
    switch (Op)
    {
    case '+':
        return ((a)+(b));
        break;
    case '-':
        return ((a)-(b));
        break;
    case '*':
        return ((a)*(b));
        break;
    case '/':
        return ((a)/(b));
        break;
    default:
        break;
    }
}

int IsOPND(char a){                //判斷是否為運算元
    if(a >='!'&&a<='/') return 0;
    else return 1;
}

int main(){

    SqStack_char OPTR ; //operator 運算子
    SqStack_int OPND;// operand 運算元
    InitStack(OPTR);
    InitStack(OPND);

    cout <<"Input the number to calculate # means the end"<<endl;
    char ch;
    cin >> ch;                                                   //先將#壓入棧OPTR
    Push(OPTR,'#');
    while(ch != '#' || GetTop(OPTR) != '#'){                   //表示式未結束或OPTR棧頂元素不為#,則繼續進行運算
        if(IsOPND(ch)){                                        //若ch輸入為運算元,則壓入棧OPND,讀入下一個字元
            Push(OPND,(ch-48));
            cin >> ch;
        }else
        {
            switch(Precede(GetTop(OPTR),ch))                   //OPTR的棧頂元素與ch輸入比較優先順序
            {
                case '<':                                      //若<,則將ch壓入棧OPTR,讀入下一個字元
                    Push(OPTR,ch);
                    cin >> ch;
                    break;
                case '>':                                      //若>,則對棧頂元素進行運算,                                        
                    char theta;                                //運算完成後,ch繼續與下一個棧頂元素進行比較
                    int a,b;
                    pop(OPTR,theta);
                    pop(OPND,a);pop(OPND,b);
                    Push(OPND,Operate(a,theta,b));
                    break;
                case '=':                                     //只有()匹配才會產生=,匹配到,則表示棧頂元素為(,把(彈出
                    char x;                                    //,讀入下一個字元
                    cin >> ch;
                    pop(OPTR,x);
            }
        }
        
        
    }
    cout << GetTop(OPND);
    system("pause");
    return 0;
}