中缀表达式到后缀表达式的转换

摘要:
(1)中缀表达式就是我们平常所说的计算表达式 如 1+2+3;
(2)后缀表达式就是将操作符号置于数的后面 1 2 + 3 +;
(将中缀表达式转换成后缀表达式的好处),计算机可以不用关心运算符号的优先级,直接按顺序读取。
(3)一个简单的算法用到数据结构:栈,将中缀表达式转换为后缀表达式:
{1}当读到一个操作数时,将它直接输出,当读到一个操作符号时,不将它输出,而是存放到栈里面。当遇到左括号(时也要放入栈中
{2}如果遇见一个右括号,就将它弹出(不输出),一直弹出操作符,直到遇见一个左括号(不输出)。
{3}如果遇见其他任何操作符,那么将检测它下面的符号优先级是否更低,如果是,则放入,如果不是,则一直弹出操作符,直到遇见优先级更低的符号为止。
{4}有一个例外,那就是弹出过程遇见一个“(”时,除非有“)”,否则不弹出“(”,(即弹出过程到此停止)。
{5}当确保入栈符号优先级最高后,再将其入栈。
(4)算法的分析,显然优先级高的操作符号总是位于栈的顶端,这也就意味着优先级高的总是先输出,那么计算机按顺序读入后缀也是符合中缀的优先级的。同时(,)保证了一个括号内的操作符与其他隔离开。
(5)注意的细节:{1}要注意处理小数点时的特殊情况(这会增加不少代码)。
{2}提前做好相关数据结构与优先级的定义.
{3}对幂运算要做单独的处理,因为它的优先级是从右到左的。(这也会增加不少代码)

// chap3_栈中缀后缀表达.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "malloc.h"
#include "stdlib.h"
#define EmptyTos -1
#define Left_bracket 50
#define Right_bracket 51
#define Power 45
#define Multiply 40
#define Divide 40
#define Plus 30
#define Subtract 30
typedef struct StackRecord *Stack;

struct StackRecord
{
    int Cpapcity;
    int TopStack;
    char *Array;

};

void Push(Stack S,char X)
{
    if(S->TopStack >= S->Cpapcity-1)
    {
        puts("cannot push an elements into a full stack");
        return;
    }
    else
        S->Array[++S->TopStack] = X;
}
char Pop(Stack S)
{
    if (S->TopStack == EmptyTos)
    {
        puts("cannot Pop an empty stack");
        exit(-1);
    }
    else
        return(S->Array[S->TopStack --]);
}
void GetPriority(char Expression,int *ThisSymbol)//获取相应的优先级
{
    switch(Expression)
        {
        case '+': *ThisSymbol = Plus;
            break;
        case '-': *ThisSymbol = Subtract;
            break;
        case '*': *ThisSymbol = Multiply;
            break;
        case '/': *ThisSymbol = Divide;
            break;
        case '^':*ThisSymbol = Power;
            break;
        case '(': *ThisSymbol = Left_bracket;
            break;
        case ')': *ThisSymbol = Right_bracket;
            break;
        default: 
            puts("there is wrong symbol");
            return;
        }
    }


void Convert(Stack S,char *Expression)//中缀表达式变成后缀
{
    int TopSymbol = 0;
    int ThisSymbol = 0;
    int k = 0;
    char OutPut[100];

    for(int i = 0;Expression[i] !='\0';i++)
{
    if ((Expression[i]<='9'&&Expression[i]>='0')||Expression[i] == '.')
        //处理数字
        OutPut[k++] = Expression[i];
    else 
    {   //处理操作符
        GetPriority(Expression[i],&ThisSymbol);
        //如果是空栈,先加入一个初始元素
        if (S->TopStack == EmptyTos)
        {
            Push(S,Expression[i]);
            TopSymbol = ThisSymbol;
            continue;
        }

        //如果不是空栈,进行比较
            if  (ThisSymbol == Right_bracket)
                //处理右括号
            {
                while(S->Array[S->TopStack]!='('&&S->TopStack !=EmptyTos)
                {
                    OutPut[k++] = Pop(S);               
                }
                if (S->TopStack ==EmptyTos)
                {
                 //处理括号不匹配
                 puts("the brackets are not balanced");
                 return ;
                }
                //括号匹配,弹出‘(’
                Pop(S);//弹出‘(’,但不输出
                if (S->TopStack == EmptyTos)
                {  //处理空的栈,将优先级设置为0.
                    TopSymbol = 0;
                    continue;
                }
              //处理不空的栈,将优先级设置为TOPSTACK的相应级别.
                GetPriority(S->Array[S->TopStack],&TopSymbol);
            }

            else
                //处理情况其他符号 <= 直到弹出优先级更低的符号
            {
                if (ThisSymbol > TopSymbol)
                {//处理情况1
                    Push(S,Expression[i]);
                    TopSymbol = ThisSymbol ;
                }
                else
            {
                do
                {
                    if(TopSymbol == Left_bracket)
                    {
                        //处理左括号
                        break;
                    }

                    else if (ThisSymbol == Power)//处理幂运算 ^,从右到左
                  {  
                      if(ThisSymbol == TopSymbol)
                          break;
                  }

                    else
                { //处理 + - * / ( 从左到右

                     OutPut[k++] = Pop(S);
                     if(S->TopStack == EmptyTos)
                     break;
                     GetPriority(S->Array[S->TopStack],&TopSymbol); 
                }   

          }while (ThisSymbol <= TopSymbol);
                //处理弹出后的元素,Push一下   
                Push(S,Expression[i]);
                TopSymbol = ThisSymbol ;
                }
    }
    }
}
    while(S->TopStack != EmptyTos)
    {
        OutPut[k++] = Pop(S);
    }
    OutPut[k] = 0;
    puts(OutPut);
    return;
}

Stack CreateStack(int MaxElements)
{
    Stack S;
    S = (Stack)malloc(sizeof( StackRecord));
    S->Array = (char*)malloc(sizeof(char)*MaxElements);
    S->TopStack = EmptyTos;
    S->Cpapcity = MaxElements;
    return S;
}


int _tmain(int argc, _TCHAR* argv[])
{
char Expression[100] = {0} ;
Stack S;
S = CreateStack(100);
puts("Please input the expression");
scanf("%s", Expression);
Convert(S,Expression);

system("pause");
    return 0;
}

结果实例:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值