中缀表达式求值、后缀表达式求值、中缀转后缀、前缀

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
前缀求值,中缀转前缀: 与后缀表达式不同之处:从右至左扫描,最终逆序输出(输出时操作符在前,操作数在后。)。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页