后缀表达式求值及中缀表达式转后缀表达式

关于后缀表达式的计算机求值以及中缀表达式转后缀表达式的分析请看我的另一篇博客——中缀表达式转前、后缀表达式及其求值

后缀表达式求值

#include<iostream> 
#include<iomanip>
#include<cstdlib>
#include<cctype> 
#include<cmath>
using namespace std;
#define MaxSize 100              //堆栈元素的最大个数
#define MaxOP 100                //运算数序列可能的最大长度
#define Number 0                 //运算数的标识 
#define ZERO 1.0E-10             //ZERO无限接近于0 
typedef double ElementType;         //将堆栈元素类型具体化 
typedef struct SNode *Stack;
struct SNode{
    ElementType data[MaxSize];
    int top;
};
//建立空栈 
Stack CreateStack()
{
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->top = -1;
    return S;
}
//入栈
void Push(Stack PtrS,ElementType X)
{
    if(PtrS->top==MaxSize-1)
        cout<<"堆栈满"<<endl;  
    else
        PtrS->data[++(PtrS->top)]=X;
 } 
//出栈
#define Error -1
ElementType Pop(Stack PtrS)
{
    if(PtrS->top==-1){
        cout<<"空栈"<<endl;
        return Error; 
    }else{
        return (PtrS->data[(PtrS->top)--]);
    }
}

int GetOp(char s[])
{
    /*从输入中获得下一个对象(运算符或运算数),并保存在字符数组s里*/
    /*返回值为Number或者运算符本身*/
    int i,c;

    /*跳过表达式前空格等字符*/
    while((s[0] = c = getchar()) == ' '||c == '\t');

    s[1] = '\0';
    if(!isdigit(c)&&c!='.')          //如果c是运算符 
        return c;                    //直接返回运算符 
    i = 0; 
    if(isdigit(c))                  //如果c是数字,则一直读完连续的数字并存入s 
        while(isdigit(s[++i] = c = getchar()));
    if(c == '.')                    //如果有小数点,则一直读完小数点后的连续数字 
        while(isdigit(s[++i] = getchar()));
    s[i] = '\0';                    //完成对实数字符串的存储 

    return Number;
 } 
//例子 
int main()
{
    int Type;
    ElementType pre;
    char s[MaxOP];
    Stack Ptr = CreateStack();

    while((Type = GetOp(s)) != EOF){  //当未读到输入结束时 
        switch(Type){
            case Number:Push(Ptr,atof(s));  
                    break;
            case'+':Push(Ptr,Pop(Ptr)+Pop(Ptr));
                    break;
            case'*':Push(Ptr,Pop(Ptr)*Pop(Ptr));
                    break;
            case'-':pre = Pop(Ptr);
                    Push(Ptr,Pop(Ptr)-pre);
                    break;
            case'/':pre = Pop(Ptr);
                    if(fabs(pre) > ZERO)       //检查除法的分母是否为0
                        Push(Ptr,Pop(Ptr)/pre);
                    else
                        cout<<"error:zero divisor"<<endl; 
                    break;
            case'\n':cout<<setprecision(8)<<Pop(Ptr)<<endl; //小数点后最多显示8位小数(精度为8) 
                     break;
            default:cout<<"error:unknown command "<<s<<endl;
                     break;
        } 
    }
    free(Ptr);
    return 0;
}

中缀表达式转后缀表达式

#include<iostream>
#include<cstdlib>
#include<cctype>
using namespace std;
#define MaxSize 100              //堆栈元素的最大个数
#define MaxOP 100                //运算数序列可能的最大长度
typedef char ElementType;         //将堆栈元素类型具体化
typedef struct SNode *Stack;
struct SNode{
    ElementType data[MaxSize];
    int top;
};
//建立空栈 
Stack CreateStack()
{
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->top = -1;
    return S;
}
//入栈
void Push(Stack PtrS,ElementType X)
{
    if(PtrS->top==MaxSize-1)
        cout<<"堆栈满"<<endl;  
    else
        PtrS->data[++(PtrS->top)]=X;
 } 
//出栈
#define Error -1
ElementType Pop(Stack PtrS)
{
    if(PtrS->top==-1){
        cout<<"空栈"<<endl;
        return Error; 
    }else{
        return (PtrS->data[(PtrS->top)--]);
    }
}
//优先级函数 
int prior(char a)
{
    if(a == '+' || a == '-')
        return 1;
    if(a == '*' || a == '/')
        return 2;
}
//转换函数 
void Transfer(char a[],Stack PtrS)
{
    int i = 0;
    while(1)
    {
        if(a[i] == '\0')  //遇到结束符
        {
            if(PtrS->top == -1)  //此时如果栈顶为空就返回
                return;
            else
            //如果栈不为空则将栈内所有元素出栈
            {
                while(PtrS->top != -1)
                {
                    cout<<Pop(PtrS)<<" ";
                }
                return;
            }
        }
        else if(isdigit(a[i]))
        //如果是数字则直接输出
        {
            while(isdigit(a[i])){        //当a[i]是数字时,则输出连续的数字
                cout<<a[i];
                i++;
            }
            if(a[i] == '.'){             //如果有小数点,则一直输出完小数点后的连续数字 
                cout<<a[i];
                i++;
                while(isdigit(a[i])){
                    cout<<a[i];
                    i++;
                }
            }
            cout<<" ";
            continue;
        }
        else if(PtrS->top == -1)
        //如果不是数字,只能是运算符,判断此时堆栈有没有元素
        //如果堆栈没有元素,将运算符压入堆栈
        {
            Push(PtrS,a[i]);
            i++;
            continue;
        }

        else if(a[i] == '(')   //遇到左括号,直接压入堆栈
        {
            Push(PtrS,a[i]);
            i++;
            continue;
        }
        else if(a[i] == ')')   
        //遇到右括号,将堆栈中的元素弹出并输出,直到遇到左括号,最后将左括号弹出
        //左括号不输出
        {
            while(PtrS->data[PtrS->top] != '(')
                cout<<Pop(PtrS)<<" ";
            Pop(PtrS);
            i++;
            continue;
        }
        else
        //既不是左括号,也不是右括号,堆栈也不为空
        //那么比较运算符与栈顶元素的优先级
        {
            while(1)
            {
                if(PtrS->top == -1 || prior(a[i]) > prior(PtrS->data[PtrS->top]) || PtrS->data[PtrS->top] == '(')
                //如果栈顶为空或者优先级大于栈顶元素或者栈顶元素是左括号
                //那么将元素压入堆栈
                {
                    Push(PtrS,a[i]);
                    break;
                }
                else
                {
                    cout<<Pop(PtrS)<<" ";  //弹出一个元素并输出
                }
            }
            i++;
            continue;
        }  
    }

    return;
}

int main()
{
    Stack Ptr = CreateStack();
    char s[MaxOP];
    cin>>s;
    Transfer(s,Ptr);
    free(Ptr); 
    return 0;
 } 
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值