zoukankan      html  css  js  c++  java
  • 中缀表达式转换成后缀表达式

    优先级:*,\ > +, -

     
    如果输入运算符的优先级低于或等于栈顶的操作符优先级,则栈内元素进入输入队列,输入运算符入栈。
     
     
    一个简单的例子
    算法示意图,使用了3个空间。输入用符号代替,如果输入是一个数字则直接进输出队列,即图中 b),d),f),h)。如果输入是运算符,则压入操作符堆栈,即图中 c),e),但是,如果输入运算符的优先级低于或等于运算符栈顶的操作符优先级,则栈内元素进入输出队列,输入操作符压入运算符堆栈,即图中 g)。 最后,运算符堆栈内元素入输出队列,算法结束.
    输入:3+4
    1. 将3入输出队列(每当输入一个数字时,直接进入输出队列)
    2. 将+号压入运算堆栈
    3. 将4入输出队列
    4. 输入结束,将操作符堆栈中剩余操作符入输出队列
    5. 在本情况下只有+号
    6. 输出 3 4 +

    通过这个例子可以看出两条规则:

    • 当读入一个数字时直接入输出队列
    • 当输入结束后,运算符队列中所有操作符入输出队列

    [编辑]






    更详细的例子


    输入: 3 + 4 * 2 / ( 1 − 5 ) ^ 2 ^ 3
    输入动作输出 (逆波兰表示法)运算符栈提示
    3 将符号加入输出队列 3    
    + 将符号压入操作符堆栈 3 +  
    4 将符号加入输出队列 3 4 +  
    * 将符号压入操作符堆栈 3 4 * + *号的优先级高于+号
    2 将符号加入输出队列 3 4 2 * +  
    / 将堆栈中元素弹出,加入输出队列 3 4 2 * + /号和*号优先级相同
    将符号压入操作符堆栈 3 4 2 * / + /号的优先级高于+号
    ( 将符号压入操作符堆栈 3 4 2 * ( / +  
    1 将符号加入输出队列 3 4 2 * 1 ( / +  
    将符号压入操作符堆栈 3 4 2 * 1 − ( / +  
    5 将符号加入输出队列 3 4 2 * 1 5 − ( / +  
    ) 将堆栈中元素弹出,加入输出队列 3 4 2 * 1 5 − ( / + 循环直到找到(号
    将堆栈元素弹出 3 4 2 * 1 5 − / + 括号匹配结束
    ^ 将符号压入操作符堆栈 3 4 2 * 1 5 − ^ / + ^号的优先级高于/号
    2 将符号加入输出队列 3 4 2 * 1 5 − 2 ^ / +  
    ^ 将符号压入操作符堆栈 3 4 2 * 1 5 − 2 ^ ^ / + ^号为从右至左求值
    3 将符号加入输出队列 3 4 2 * 1 5 − 2 3 ^ ^ / +  
    END 将栈中所有数据加入输出队列 3 4 2 * 1 5 − 2 3 ^ ^ / +  
     
    // main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "stack.h"

    int GetPriority(char ch)
    {
    switch(ch)
    {
    case '+':
    return 0;
    case '-':
    return 0;
    case '*':
    return 1;
    case '/':
    return 1;
    default:
    return -1;
    }
    }

    int IsNumber(char ch)
    {
    return (ch >= '0' && ch <= '9');
    }

    int main()
    {
    char expression[100];

    printf("please input the expression:\n");
    scanf("%s", expression);

    OperatorStack *stack = (OperatorStack*)malloc(sizeof(OperatorStack));

    stack->size = 0;

    int n = 0;
    for(n=0; n<strlen(expression); n++)
    {
    if(IsNumber(expression[n]))
    {
    printf("%c", expression[n]);
    }
    else
    {
    if(expression[n] == '(')
    {
    Push(stack, expression[n]);
    }
    else if(expression[n] == ')')
    {
    while(GetTop(stack) != '(')
    {
    printf("%c", Pop(stack));
    }

    Pop(stack);
    }
    else
    {
    // operators: +, -, *, /
    if(IsEmpty(stack))
    {
    Push(stack, expression[n]);
    }
    else
    {
    while(!IsEmpty(stack) && GetPriority(GetTop(stack)) >= GetPriority(expression[n]))
    {
    printf("%c", Pop(stack));
    }

    Push(stack, expression[n]);
    }
    }
    }
    }

    while(!IsEmpty(stack))
    {
    printf("%c", Pop(stack));
    }

    printf("\n");

    return 0;
    }
    // stack.h
    #ifndef _OPERATOR_STACK_H_
    #define _OPERATOR_STACK_H_

    #define STACK_LENGTH 100

    typedef struct OperatorStack
    {
    char operator_stack[STACK_LENGTH];
    int size;
    }OperatorStack;

    int Push(OperatorStack *stack, char ch);
    char Pop(OperatorStack *stack);
    int IsEmpty(OperatorStack *stack);
    char GetTop(OperatorStack *stack);

    #endif
    // stack.c
    #include "stack.h"

    int Push(OperatorStack *stack, char ch)
    {
    if(stack->size >= STACK_LENGTH)
    {
    // Error: stack is full
    return 0;
    }

    stack->operator_stack[stack->size] = ch;
    stack->size++;

    return 1;
    }

    char Pop(OperatorStack *stack)
    {
    if(stack->size <= 0)
    {
    return -1;
    }

    stack->size--;
    return stack->operator_stack[stack->size];
    }

    char GetTop(OperatorStack *stack)
    {
    if(stack->size == 0)
    {
    return -1;
    }

    return stack->operator_stack[stack->size - 1];
    }

    int IsEmpty(OperatorStack *stack)
    {
    return stack->size == 0;
    }



  • 相关阅读:
    js 计时器小练-20160601
    数位dp入门学习之路(正常枚举“过渡到”dfs枚举)
    An easy problem
    牌型种类 蓝桥杯
    带分数(穷举法) 蓝桥杯赛题
    表达式的转换----->中缀表达式转后缀表达式
    map 的使用
    netsatat 的使用
    两个矩形不相交
    前缀和
  • 原文地址:https://www.cnblogs.com/xiaobo68688/p/2376700.html
Copyright © 2011-2022 走看看