前缀中缀后缀表达式

本文介绍如何使用堆栈将中缀表达式转换为后缀和前缀表达式的方法,并提供了完整的C语言代码实现。同时,文中详细解释了运算符优先级的设定及其在转换过程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中缀表达式转换为前缀表达式的3种方法,链接如下:

http://wenku.baidu.com/view/0a1d3b365a8102d276a22f85.html


快要开始工作了,人生的第一份工作要格外重视,毕竟要有一个好的开始嘛。所以抽几天时间复习一下数据结构。看到堆栈部分,有一个运用堆栈的列子,表达式的中缀和前缀后缀的转换,刚开始找工作面试和笔试都遇到了这样的问题,以前模模糊糊的,现在搞明白了

一.表达式的三种形式:

中缀表达式:运算符放在两个运算对象中间,这是我们书写的时候最熟悉的一种形式,如:(2+1)*3

后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:2 1 + 3 *

前缀表达式:同后缀表达式一样,不包含括号,运算符放在两个运算对象的前面,如:* + 2 1 3

二.中缀表达式向后缀和前缀表达式的转换

转化的过程需要一个辅助的运算符堆栈op。并且要预先给运算符设置好运算的优先级如下所示:

?
struct
{
     char  ch;
     int  pri;
}
lpri[]={{ '=' ,0},{ '(' ,1},{ '*' ,5},{ '/' ,5},{ '+' ,3},{ '-' ,3},{ ')' ,6}},
rpri[]={{ '=' ,0},{ '(' ,6},{ '*' ,4},{ '/' ,4},{ '+' ,2},{ '-' ,2},{ ')' ,1}};

  我们可以看到同一个运算符作为左(对应lpri数组)、右(对应rlpri数组)运算符时他们的优先级不同,这是为了实现表达式求值时"从左到右计算"的规定设计的。为了方便算法的实现,在op堆栈的栈地存放的是'='作为终结。

将算术表达式exp转换成后缀表达式postexp的过程如下:

 

?
初始化运算符堆栈op;
 
'=' 进栈;
 
exp 读取字符ch;
 
while (ch!= '\0' )
{
      if (ch不是运算符)
           将后续的所有数字均依次存放到postexp中,并以字符 '#' 标志数值串的结束;
    else
            switch (precede(op的栈顶运算符,ch))
            {
              case  '<' :     //栈顶运算符优先级低
                将ch进栈;
                exp 读取下一个字符ch;
                break
          case  '=' :
                        退栈;
                exp 读取下一个字符ch;
                break
          case  '>' :
                       退栈运算符并将其存放到postexp中;
                break
          }
}
 
若字符串 exp 扫描完毕,则将运算符栈op中 '=' 之前的所有运算符依次出栈并存放到
postexp中。最后得到后缀表达式postexp。

 

 具体的C语言代码如下:

?
#include "stdafx.h"
#include <iostream>
 
#define MaxOp 10
#define MaxSize 50
 
struct
{
     char  ch;
     int  pri;
}
lpri[]={{ '=' ,0},{ '(' ,1},{ '*' ,5},{ '/' ,5},{ '+' ,3},{ '-' ,3},{ ')' ,6}},
rpri[]={{ '=' ,0},{ '(' ,6},{ '*' ,4},{ '/' ,4},{ '+' ,2},{ '-' ,2},{ ')' ,1}};
 
int  leftpri( char  op)
{
     int  i;
     for (i=0;i<MaxOp;i++)
         if (lpri[i].ch==op) return  lpri[i].pri;
}
 
int  rightpri( char  op)
{
     int  i;
     for (i=0;i<MaxOp;i++)
         if (rpri[i].ch==op) return  rpri[i].pri;
}
 
 
 
int  isOp( char  ch)
{
     if (ch== '(' ||ch== ')' ||ch== '*' ||ch== '/' ||ch== '+' ||ch== '-' )
         return  1;
     else
         return  0;
}
 
int  precede( char  op1, char  op2)
{
     if (leftpri(op1)==rightpri(op2))
         return  0;
     else
         if (leftpri(op1)<rightpri(op2))
             return  -1;
         else
             return  1;
}
 
int  precedeT( char  op1, char  op2)
{
     if (leftpri(op1)==rightpri(op2))
         return  0;
     else
         if (leftpri(op1)<rightpri(op2))
             return  1;
         else
             return  -1;
}
 
 
 
void  trans( char  * exp , char  postexp[])
{
     
     typedef  struct
     {
         char  data[MaxSize];
         int  top;
     }OP;
 
     OP *op=(OP *) malloc ( sizeof (OP));
     int  i=0;
     op->top=-1;
     op->top++;
     op->data[op->top]= '=' ;
 
 
     while (* exp != '\0' )
     {
         if (!isOp(* exp ))
         {
             while (* exp >= '0' &&* exp <= '9' )
             {
                 postexp[i++]=* exp ;
                 exp ++;
             }
             postexp[i++]= '#' ;
         } else
             switch (precede(op->data[op->top],* exp ))
         {
             case  -1:
                 op->data[++op->top]=* exp ;
                 exp ++;
                 break ;
             case  0:
                 op->top--;
                 exp ++;
                 break ;
             case  1:
                 postexp[i++]=op->data[op->top--];
                 break ;
         }
     }
     while (op->data[op->top]!= '=' )
     {
         postexp[i++]=op->data[op->top--];
     }
     postexp[i]= '\0' ;
     
}
 
void  transT( char  * exp , char  postexp[])
{
     
     typedef  struct
     {
         char  data[MaxSize];
         int  top;
     }OP;
 
     OP *op=(OP *) malloc ( sizeof (OP));
     int  i=0;
     op->top=-1;
     op->top++;
     op->data[op->top]= '=' ;
     int  j=-1;
     char  *p= exp ;
     while (*p!= '\0' )
     {
         p++;
         j++;
     }
 
     while (j>-1)
     {
         if (!isOp( exp [j]))
         {
             while ( exp [j]>= '0' && exp [j]<= '9' )
             {
                 postexp[i++]= exp [j];
                 j--;
             }
             postexp[i++]= '#' ;
         } else
             switch (precedeT( exp [j],op->data[op->top]))
         {
             case  -1:
                 op->data[++op->top]= exp [j];
                 j--;
                 break ;
             case  0:
                 op->top--;
                 j--;
                 break ;
             case  1:
                 postexp[i++]=op->data[op->top--];
                 break ;
         }
     }
     while (op->data[op->top]!= '=' )
     {
         postexp[i++]=op->data[op->top--];
     }
     postexp[i]= '\0' ;
     
}
 
float  compvalue( char  *postexp)
{
     typedef  struct
     {
         float  data[MaxSize];
         int  top;
     }OP;
 
     float  a,b,c,d;
     OP *st = (OP *) malloc ( sizeof (OP));
     st->top=-1;
     while (*postexp!= '\0' )
     {
         switch (*postexp)
         {
         case  '+' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             c=a+b;
             st->data[++st->top]=c;
             break ;
         case  '-' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             c=b-a;
             st->data[++st->top]=c;
             break ;
         case  '*' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             c=b*a;
             st->data[++st->top]=c;
             break ;
         case  '/' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             if (a!=0)
             {
                 c=b/a;
                 st->data[++st->top]=c;
             }
             else
             {
                 printf ( "\0除零错误!\n" );
                 exit (0);
             }
             break ;
         default :
             d=0;
             while (*postexp>= '0' &&*postexp<= '9' )
             {
                 d=10*d + *postexp - '0' ;
                 postexp++;
             }
             st->data[++st->top]=d;
             break ;
         }
         postexp++;
     }
     return  st->data[st->top];
}
 
float  compvalueT( char  *postexp)
{
     typedef  struct
     {
         float  data[MaxSize];
         int  top;
     }OP;
 
     float  a,b,c,d;
     OP *st = (OP *) malloc ( sizeof (OP));
     st->top=-1;
     while (*postexp!= '\0' )
     {
         switch (*postexp)
         {
         case  '+' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             c=a+b;
             st->data[++st->top]=c;
             break ;
         case  '-' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             c=a-b;
             st->data[++st->top]=c;
             break ;
         case  '*' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             c=a*b;
             st->data[++st->top]=c;
             break ;
         case  '/' :
             a=st->data[st->top--];
             b=st->data[st->top--];
             if (b!=0)
             {
                 c=a/b;
                 st->data[++st->top]=c;
             }
             else
             {
                 printf ( "\0除零错误!\n" );
                 exit (0);
             }
             break ;
         default :
             d=0;
             while (*postexp>= '0' &&*postexp<= '9' )
             {
                 d=10*d + *postexp - '0' ;
                 postexp++;
             }
             st->data[++st->top]=d;
             break ;
         }
         postexp++;
     }
     return  st->data[st->top];
}
 
int  _tmain( int  argc, _TCHAR* argv[])
{
 
     char  exp []= "1+((2+3)*4)-5" ;
     //char expT[]="1+((2+3)*4)-5";
     
     
     
     //fanzhuan(exp,expT);
     //printf("expT:%s\n",expT);
 
     char  postexp[MaxSize];
     char  postexpT[MaxSize];
     trans( exp ,postexp);
     
 
     printf ( "中缀表达式:%s\n" , exp );
     printf ( "后缀表达式:%s\n" ,postexp);
     transT( exp ,postexpT);
     printf ( "前缀表达式:%s\n" ,postexpT);
     printf ( "后缀表达式的值:%f\n" ,compvalue(postexp));
     printf ( "前缀表达式的值:%f\n" ,compvalueT(postexpT));
 
     return  0;
}

 

哈哈,上面的代码已经包括中缀转前后缀和前后缀的求值算法实现了。

前缀和后缀表达式转换方法的区别主要在,后缀是从左往右扫描exp,前缀反之。所以两者的左右运算符的划分是相反的。这一点还体现在求值的时候。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值