中綴表達式求值、後綴表達式求值、中綴轉後綴、前綴

1.中綴表達式求值

兩個棧:OPND(double類數),OPTR(操作符)。
需要比較棧裏和棧外ch的操作符優先級。
運用到atof()函數(stdlib.h),將*char 轉換爲 double。

#include<iostream>
#include<iomanip>
#include<string.h>
#include<stdlib.h>
using namespace std;


#define MAXSIZE 1000

typedef struct
{
    double *base;
    double *top;
    int stacksize;
}SqStack_d;

void Init(SqStack_d &S)
{
    S.base = new double[MAXSIZE];
    S.top = S.base;
    S.stacksize = MAXSIZE;
}

void Push(SqStack_d &S, double e)
{
    if(S.top - S.base != S.stacksize)
    {
        *S.top  = e;
        S.top++;
    }
}

void Pop(SqStack_d &S, double &e)
{
    if(S.top !=S.base)
    {
        S.top--;
        e = *S.top;
    }
}

double GetTop(SqStack_d S)
{
    if(S.base !=S.top)
    {
        return *(S.top-1);
    }
}


typedef struct
{
    char *base;
    char *top;
    int stacksize;
}SqStack_c;

void Init(SqStack_c &S)
{
    S.base = new char[MAXSIZE];
    S.top = S.base;
    S.stacksize = MAXSIZE;
}

void Push(SqStack_c &S, char e)
{
    if(S.top - S.base != S.stacksize)
    {
        *S.top  = e;
        S.top++;
    }
}

void Pop(SqStack_c &S, char &e)
{
    if(S.top !=S.base)
    {
        S.top--;
        e = *S.top;
    }
}

char GetTop(SqStack_c S)
{
    if(S.base !=S.top)
    {
        return *(S.top-1);
    }
}


bool In( char ch)
{
    if(ch>='0'&&ch<='9')
    {
        return true;
    }
    else return false;
}


char Com(char c1,char c2)   //c1:in c2:out or ch
{
    if((c1=='('&&c2==')')||(c1=='='&&c2=='='))
        return '=';
    else if(((c1=='+'||c1=='-')&&(c2=='+'||c2=='-'||c2==')'||c2=='='))||((c1=='*'||c1=='/'||c1==')')&&(c2=='+'||c2=='-'||c2=='*'||c2=='/'||c2==')'||c2=='=')))
        return '>';
    else return '<';
}


double Operate(double a,char x,double b)    //  ASCALL
{
    switch(x)
    {
    case '+':
        return (a+b);
        break;
    case '-':
        return (a-b);
        break;
    case '*':
        return (a*b);
        break;
    case '/':
        return (a/b);
        break;
    }   
}


double Expression(char s[])
{                           //  5*(7-3)#
    SqStack_d OPND;
    SqStack_c OPTR;
    Init(OPND);
    Init(OPTR);
    Push(OPTR,'='); //# 要入棧
    char ch;
    int k=0;
    ch = s[k];  
    double item;
    while(ch != '=' || GetTop(OPTR)!='=')   // GetTop(OPTR)!='=' 防止ch== '=',OPTR中還有操作符
    {
        if(In(ch))  // ch = 4  .5
        {
            char sd[MAXSIZE];
            memset(sd,0,sizeof(sd));
            int i=0;
            while((ch>='0'&&ch<='9')||(ch=='.'))
            {
                sd[i] = ch;
                k++;
                ch = s[k];
                i++;
            }
            item = atof(sd);
            Push(OPND,item);
        }
        else
        {
            switch(Com(GetTop(OPTR),ch))
            {
            case '<':
                {
                    Push(OPTR,ch);
                    k++;
                    ch = s[k];
                    break;
                }
            case '>':
                {
                    double a,b;
                    char op;
                    Pop(OPTR,op);
                    Pop(OPND,a);
                    Pop(OPND,b);
                    Push(OPND,Operate(b,op,a));
                    break;  // can't cin>>ch
                }
            case '=':
                    {
                        char x;
                        Pop(OPTR,x);
                        k++;
                        ch = s[k];
                        break;
                    }
            }
        }
    }
    return GetTop(OPND);
}

int main()
{
    char s[MAXSIZE];
    while(1)
    {
        cin>>s;
        if(s[0] == '=')
            {break;}
        cout<<setiosflags(ios::fixed)<<setprecision(2)<<Expression(s)<<endl;
    }
    return 0;
}

OJ上樣例

還待優化:兩個棧,如何用一個共享棧,共用體結構;是否可以只用一個char棧

2. 後綴表達式求值

後綴表達式(從左向右掃描),表達式中的操作符已包含優先級,且無括號操作符,無需再比較優先級。
比中綴表達式簡單
一個棧:OPND(double操作數)

#include<iostream>
#include<iomanip>
#include<string.h>
#include<stdlib.h>
using namespace std;


#define MAXSIZE 1000

typedef struct
{
    double *base;
    double *top;
    int stacksize;
}SqStack_d;

void Init(SqStack_d &S)
{
    S.base = new double[MAXSIZE];
    S.top = S.base;
    S.stacksize = MAXSIZE;
}

void Push(SqStack_d &S, double e)
{
    if(S.top - S.base != S.stacksize)
    {
        *S.top  = e;
        S.top++;
    }
}

void Pop(SqStack_d &S, double &e)
{
    if(S.top !=S.base)
    {
        S.top--;
        e = *S.top;
    }
}

double GetTop(SqStack_d S)
{
    if(S.base !=S.top)
    {
        return *(S.top-1);
    }
}




double Operate(double a,char x,double b)    //  ASCALL
{
    switch(x)
    {
    case '+':
        return (a+b);
        break;
    case '-':
        return (a-b);
        break;
    case '*':
        return (a*b);
        break;
    case '/':
        return (a/b);
        break;
    }   
}


double Expression(char s[])
{                           //  12+=
    SqStack_d OPND;
    Init(OPND);
    char ch;
    int k=0;
    ch = s[0];
    while(ch != '=')    // OPND不足,有剩
    {
        if(ch>='0'&&ch<='9')    
        {
            int flag =1;
            double x;
            x = ch-48;
            Push(OPND,x);
        }
        else
        {
            int flag = 0;
            double a,b;
            Pop(OPND,a);    //2
            Pop(OPND,b);    //1
            Push(OPND,Operate(b,ch,a));
        }
        k++;
        ch = s[k];
    }
    return GetTop(OPND);
}

int main()
{
    char s[MAXSIZE];
    while(1)
    {
        cin>>s;
        if(s[0] == '=')
            {break;}
        cout<<setiosflags(ios::fixed)<<setprecision(2)<<Expression(s)<<endl;
    }
    return 0;
}

這裏寫圖片描述

3.中綴轉後綴

一個 棧:OPTR(操作符)
從左向右掃描 中綴表達式 :
遇數,輸出;
遇符:
棧裏<棧外,棧外進棧,輸入下一個字符;
棧裏==棧外,pop,輸入下一個字符;
棧裏>棧外,棧裏pop,並輸出。



#include<iostream>
#include<string>
using namespace std;

#define MAXSIZE 1000

typedef struct
{
    char *base;
    char *top;
    int stacksize;
}SqStack_c;

void Init(SqStack_c &S)
{
    S.base = new char[MAXSIZE];
    S.top = S.base;
    S.stacksize = MAXSIZE;
}

void Push(SqStack_c &S, char e)
{
    if(S.top - S.base != S.stacksize)
    {
        *S.top++ = e;
    }
}

void Pop(SqStack_c &S, char &e)
{
    if(S.top !=S.base)
    {
        S.top--;
        e = *S.top;
    }
}

char GetTop(SqStack_c S)
{
    if(S.base !=S.top)
    {
        return *(S.top-1);
    }
}


char Com(char c1,char c2)
{
    if(((c1=='+'||c1=='-')&&(c2=='+'||c2=='-'||c2==')'||c2=='='))||((c1=='*'||c1=='/'||c1==')')&&(c2=='+'||c2=='-'||c2=='*'||c2=='/'||c2==')'||c2=='=')))
    {
        return '>';
    }
    else if((c1=='='&&c2=='=')||(c1=='('&&c2==')'))
    {
        return '=';
    }
    else
    {
        return '<';
    }
}

void Mid_to_Pos(string s)
{
    SqStack_c OPTR;
    Init(OPTR);
    int k=0;
    char ch = s[0];
    Push(OPTR,'=');
    while(ch!='=' || GetTop(OPTR)!= '=')
    {
        if(ch>='0'&&ch<='9')
        {
            cout<<ch;
            ch = s[++k];
        }
        else
        {
            switch(Com(GetTop(OPTR),ch))
            {
            case '>':
                char e;
                Pop(OPTR,e);
                cout<<e;
                break;
            case '<':
                Push(OPTR,ch);
                ch = s[++k];
                break;
            case '=':
                char x;
                Pop(OPTR,x);
                ch = s[++k];
                break;
            }
        }
    }
    cout<<endl;
}

int main()
{
    while(1)
    {
        string s;
        cin>>s;
        if(s =="=")
        {
            break;
        }
         Mid_to_Pos(s);
    }
}

這裏寫圖片描述

4.關於前綴

中綴表達式“1+((2+3)4)-5” 轉前綴:- + 1 + 2 3 4 5
前綴求值,中綴轉前綴: 與後綴表達式不同之處:從右至左掃描,最終逆序輸出(輸出時操作符在前,操作數在後。)。

發佈了28 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章