中缀表达式转后缀表达式

后缀表达式概述:

        后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。

转后缀表达式的具体做法:

        建立一个栈Stack 。从左到右扫描表达式,如果读到非符号就将它输出,如果读到运算符则进行压栈操作(需要判断符号优先级)。

优先级判断:

        如果栈顶符号的优先级大于等于当前符号,则将栈顶符号弹出,直到栈顶符号优先级小于当前符号,再将当前符号压入栈中。

例:

        {"+", "/"} 设左侧为栈底,右侧为栈顶,当前符号为 " * "。栈顶符号 " / " 的优先级等于当前符号 " * ",则弹出 " / "。栈顶指针继续往下走,指向了 " + ",当前符号优先级大于 " + " ,则把当前符号压入栈内。

代码实现(C语言):

#include <stdio.h>
#include <stdlib.h>

#define TRUE            1
#define FALSE           0
#define STACK_INIT_SIZE 15

typedef int Status;
typedef char ElemType;

typedef struct sqStack
{
    ElemType *top;
    ElemType *base;
    int stackSize;
} sqStack;

Status cls(sqStack *stack);
void clsStack(sqStack *stack);
void sqStackInit(sqStack *stack);
void destroyStack(sqStack *stack);
Status judge(sqStack *stack, ElemType e);
void Push_Pop(sqStack *stack, ElemType e);
Status priority(sqStack *stack, ElemType e);

// 申请一个容量为15的栈
void sqStackInit(sqStack *stack)
{
    stack->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if (!stack->base)
    {
        printf("栈初始化失败!");
        exit(0);
    }
    stack->top = stack->base;
    stack->stackSize = STACK_INIT_SIZE;
}

// 判断符号优先级
Status priority(sqStack *stack, ElemType e)
{
    if (stack->top == stack->base)
    {
        return TRUE;
    }
    if (e == '+' || e == '-')
    {
        do
        {
            -- stack->top;
            if (*(stack->top) == '(')
            {
                stack->top ++;
                return TRUE;
            }
            printf("%c ", *(stack->top));
        } while (stack->top != stack->base);

        return TRUE;
    }
    else
    {
        ElemType previous = *(--stack->top);
        if (previous == '+' || previous == '-')
        {
            stack->top ++;
            return TRUE;
        }
        else
        {
            if (previous == '(')
            {
                stack->top ++;
                return TRUE;
            }
            while (stack->top != stack->base){
                printf("%c ", *(stack->top));
                stack->top --;
                if (*(stack->top) == '-' || *(stack->top) == '+' || *(stack->top) == '(')
                {
                    stack->top ++;
                    return TRUE;
                }
            } ;
            printf("%c ", *(stack->top));
            return TRUE;
        }
    }
}

// 遇到右括号则在栈内找左括号, 并把括号内的符号全部弹出。
Status cls(sqStack *stack)
{
    stack->top --;
    while (*(stack->top) != '(')
    {
        printf("%c ", *(stack->top));
        stack->top --;
    }

    return FALSE;
}

// 判断符号
Status judge(sqStack *stack, ElemType e)
{
    switch (e)
    {
        case '(': return TRUE;
        case '+': return priority(stack, e);
        case '-': return priority(stack, e);
        case '*': return priority(stack, e);
        case '/': return priority(stack, e);
        case ')': return cls(stack);
        default:
            printf("%c ", e);
    }
    return FALSE;
}

// 执行压栈和弹栈
void Push_Pop(sqStack *stack, ElemType e)
{
    if (judge(stack, e))
    {
        *(stack->top) = e;
        stack->top ++;
    }
}

// 清空栈
void clsStack(sqStack *stack)
{
    if (stack->top == stack->base)
    {
        return;
    }
    do
    {
        stack->top --;
        printf("%c ", *(stack->top));
    } while (stack->top != stack->base);
}

void destroyStack(sqStack *stack)
{
    free(stack->base);
    stack->top = stack->base = NULL;
    stack->stackSize = 0;
}

int main(void)
{
    char input;
    sqStack stack;
    sqStackInit(&stack);
    
    printf("输入表达式:");

    do
    {
        scanf("%c", &input);
        if (input != '#')
        {
            Push_Pop(&stack, input);
        }
    } while (input != '#');

    getchar();

    clsStack(&stack);   // 把栈内的所有符号都弹出
    
    destroyStack(&stack);
    return 0;
}

注: 输入表达式时,以字符 " # " 结尾!

运行结果:

        >>输入表达式:1+((9-3)/2+1-3/3-1)/2#
        >>1 9 3 - 2 / 1 + 3 3 / - 1 - 2 / +

这次的代码写的有点乱,将就一下,下次再写的时候好好整理一下。

代码测试次数不多,如遇bug望告知。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值