逆波兰表达式(后缀表达式)的计算

   后缀表达式计算时,所有运算按照运算符出现的顺序,严格从左到右,每个操作符取前两个操作数进行运算,运算后的结果仍然作为下次的操作数。
那如果已知后缀表达式,如何求值:

这里写图片描述
   举一个例子:
这里写图片描述


代码:

#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<stdio.h>
//包装静态栈
#define MAX 20
typedef struct s
{
    int arr[MAX];
    int top;
}stack;
//枚举
enum Calc
{
    ADD,
    SUB,
    MUL,
    DIV,
    DATA
};
//操作
typedef struct operate
{
    enum calc op;
    int _data;
}operate;
//栈初始化
void StackInit(stack *s);
//栈顶元素
int TopStack(stack *s);
//出栈
void PopStack(stack *s);
//逆波兰表达式的求解
int CalcRPN(operate *cal, stack *s,int size);
#include"RPN.h"

void TestRPN()
{
    int size = 0;
    int ret = 0;
    stack s;
    //定义结构体数组
    operate  cal[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 }, { ADD, 0 }, { MUL, 0 },
    { DATA, 6 }, { SUB, 0 }, { DATA, 8 }, { DATA, 2 }, { DIV, 0 }, { ADD, 0 } };
    size = sizeof(cal) / sizeof(cal[0]);
    //栈初始化
    StackInit(&s);
    //逆波兰表达式的求解
    ret = CalcRPN(cal,&s,size);
    printf("ret = %d\n", ret);
}

int main()
{

    TestRPN();
    system("pause");
    return 0;
}
#include"RPN.h"

//栈初始化
void StackInit(stack *s)
{
    assert(s);
    s->top = 0;
    memset(s->arr, 0, MAX*sizeof(int));
}


//数据入栈
void PushStack(stack *s, int data)
{
    assert(s);
    if (s->top > MAX)
    {
        return;
    }
    s->arr[s->top] = data;
    s->top++;
}

//栈顶元素
int TopStack(stack *s)
{
    assert(s);
    return s->arr[s->top - 1];
}

//出栈
void PopStack(stack *s)
{
    assert(s);
    s->top--; 
}


//逆波兰表达式的求解
int CalcRPN(operate *cal, stack *s,int size)
{
    int i = 0;
    int left = 0;
    int right = 0;
    int ch = 0;
    assert(s);
    for (i = 0; i < size; i++)
    {
        if (cal->op == DATA)
        {
            //数据入栈
            PushStack(s,cal->_data);
        }
        else
        {
            ch = cal->op;
            //栈顶元素
            right = TopStack(s);
            //出栈
            PopStack(s);
            left = TopStack(s);
            //出栈
            PopStack(s);

            switch (ch)
            {
            case ADD:PushStack(s,left + right);
                break;
            case SUB:PushStack(s, left - right);
                break;
            case MUL:PushStack(s, left * right);
                break;
            case DIV:
                if (right == 0)
                {
                    printf("除数为0,非法!!!\n");
                    return 0;
                }
                else
                {
                   PushStack(s, left / right);
                }
                break;
            default:printf("操作数非法!!\n"); break;
            }
        }
        cal++;
    }
    return TopStack(s);
}

猜你喜欢

转载自blog.csdn.net/zhao_miao/article/details/81783487