中缀表达式与前缀、后缀表达式的转换

本文介绍如何将中缀表达式转换为前缀和后缀表达式的方法,包括使用栈进行运算符优先级处理的详细步骤。

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


中缀表达式:便于人看;

前缀表达式:又称波兰式,运算符在前边,运算数在后边;

后缀表达式:又称逆波兰式,运算数在前边,运算符在后边;

 

一、中缀表达式转换前缀表达式:

  1、初始化两个栈,s1(存放数字)s2(存放运算符)

  2、表达式右边开始,遍历表达式;

  3、遇到数字放入s1中,遇到运算符放入s2中,放入法则如下:

 (1)如果s2为空,或者“)”,直接放进去;

 (2)当前运算符和栈顶运算符比较,当前运算符优先级大于等于栈顶运算符优先级,直接放进去;

 (3)如果当前运算符小于栈顶运算符优先级,栈顶运算符取出来放入s1中,重复(2)(3)

 4、s1栈中的元素依次出栈,入s2栈;

 5、s2栈中元素依次出栈重新组成表达式即为前缀表达式。

 

二、中缀表达式转换后缀表达式

  1、初始化两个栈,s1(存放数字)s2(存放运算符)

  2、从表达式左边开始遍历,数字放入s1中,运算符放入s2中;

  3、运算符放入s2中的规则:

  (1)如果s2空或者栈顶是”(”,直接放进去;

  (2)如果当前运算符优先级大于栈顶元素优先级,直接放入;

 (3)如果当前运算符优先级小于等于栈顶元素优先级,栈顶元素出栈,并且s1栈;

 (4)遇到”)”,运算符出栈,入s1栈,直到遇到”(”, ”( )”要丢掉;

  4s1中的元素依次出栈,入s2栈;

  5s2栈中元素出栈重新组成表达式即为后缀表达式。

    以上算法比较试用笔试的时候计算选择或者填空题,用代码实现的时候我选择了用一个栈和一个字符串去实现。比如编程实现将中缀表达式转成前缀表达式,如a+b*(c-d)-e/f转成-+a*b-cd/ef。首先我们要考虑运算符的优先级问题,除去括号的优先级,就是先乘除后加减,我是用的定义宏来处理这个问题,当然还有更好的处理方法大家可以给我意见,定义宏比较通俗易懂所以我就暂且这样使用了。然后就开始入栈出栈了,规则是遇到字符就放到定义好的字符串中,遇到运算符就入栈。因为是中缀转前缀,所以要从右往左遍历表达式。运算符入栈的规则是,栈空时运算符直接入栈;栈不空时,当“+”或“-”入栈要与栈顶元素的优先级比较,若小于栈顶元素,需要将比即将要入栈元素大的元素都依次出栈,放入字符串中,然后将“+”或“-”入栈,反之直接入栈(注意:将优先级大的元素出栈后切勿忘了将“+”或“-”入栈);当遇到“*”或“/”入栈就直接入栈;还如注意的就是括号,如遇到“)”直接入栈,如遇到“(”须将元素依次出栈放入字符串中,直到遇到“)”即停止出栈(因为是从右至左遍历所以先遇到右括号)。遍历完字符串后接着判断栈是否为空,若不为空则将栈内元素依次出栈放入字符串中,最后逆置字符串即得到前缀表达式。

(代码实现较长,有较多重复代码,请大家见谅)

    实现代码如下:

#define LEFT 0
#define RIGHT 0
#define ADD  1
#define SUB  2
#define MULTI  3
#define DIVIDE 4
char *Reverse(char *str)
{
 assert(str!=NULL);
 int length=strlen(str);
 char tmp;
 for(int i=0,j=length-1;i< length/2;i++,j--)
 {
  tmp=str[i];
  str[i]=str[j];
  str[j]=tmp;
 }
  return str;
}
char*  Infix_Turn_Suffix(char *str)
{
 SNode p;
 InitStack(&p);
 char *arr=(char*)malloc(sizeof(char)*strlen(str));
 int top=-1;
 int tmp=-1;
 int rval;
 int j=0;
 for(int i=strlen(str)-1;i>=0;i--)
 {
  GetTop(&p,&top);
  switch(str[i])
  {
  case '+':
   while(!IsEmpty(&p))
    {
     GetTop(&p,&top);
     if(top>SUB)
     {
      Pop(&p,&rval);
      if(rval==MULTI)
      {
       arr[j]='*';
       j++;
      }
      if(rval==DIVIDE)
      {
       arr[j]='/';
       j++;
      } 
     }
     else break;
    }
    Push(&p,ADD);
   break;
  case '-':
    while(!IsEmpty(&p))
    {
     GetTop(&p,&top);
     if(top>SUB)
     {
      Pop(&p,&rval);
      if(rval==MULTI)
      {
       arr[j]='*';
       j++;
      }
      if(rval==DIVIDE)
      {
       arr[j]='/';
       j++;
      } 
     }
     else break;
    }
    Push(&p,SUB);
   break;
  case '*':
   Push(&p,MULTI);
   break;
  case '/':
   Push(&p,DIVIDE);
   break;
  case '(':
   while(rval!=LEFT)
   {
    Pop(&p,&rval);
    if(rval==ADD)
    {
     arr[j]='+';
     j++;
    }
    if(rval==SUB)
    {
     arr[j]='-';
     j++;
    }
    if(rval==MULTI)
    {
     arr[j]='*';
     j++;
    }
    if(rval==DIVIDE)
    {
     arr[j]='/';
     j++;
    }
    }
    break;
  case ')':
   Push(&p,LEFT);
   break;
  default:
   arr[j]=str[i];
   j++;
   break;
  }
 }
 if(IsEmpty(&p))
 {
  arr[j]='\0';
 }
 else
 {
  while(!IsEmpty(&p))
  {
   Pop(&p,&rval);
   if(rval==ADD)
    {
     arr[j]='+';
     j++;
    }
    if(rval==SUB)
    {
     arr[j]='-';
     j++;
    }
    if(rval==MULTI)
    {
     arr[j]='*';
     j++;
    }
    if(rval==DIVIDE)
    {
     arr[j]='/';
     j++;
    }
  }
  arr[j]='\0';
 }
 
 Reverse(arr);
 return arr;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值