问题 M: 中缀表达式转后缀表达式

问题 M: 中缀表达式转后缀表达式

题目描述
输入一个中缀表达式,编程输出其后缀表达式,要求输出的后缀表达式的运算次序与输入的中缀表达式的运算次序相一致。为简单起见,假设输入的中缀表达式由+(加)、-(减)、×(乘)、/(除)四个运算符号以及左右圆括号和英文字母组成,其中算术运算符遵守先乘除后加减的运算规则。假设输入的中缀表达式长度不超过300个字符,且都是正确的,即没有语法错误,并且凡出现括号其内部一定有表达式,即内部至少有一个运算符号。

中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。

输入
只有一行,为中缀表达式
输出
只有一行,为转换后的后缀表达式
样例输入 Copy
X+A*(Y-B)-Z/F
样例输出 Copy
XAYB-*+ZF/-

实现过程

下面是对代码的详细解析:

  1. 头文件

    • 包含 <stdio.h><string.h><stdlib.h> 头文件,分别提供输入输出、字符串操作和动态内存分配的功能。
  2. 常量定义

    • max 定义了字符数组的最大长度。
  3. 结构体定义

    • cnt 结构体定义了一个栈,包含一个字符数组 L 和一个整型 top 用于表示栈顶位置。
  4. 辅助函数 num

    • 该函数用于判断当前字符 ch 和栈顶字符 ch2 是否满足运算符优先级的规则。
    • 如果当前字符是 +-,并且栈顶字符是 +-*/,则返回1,表示不符合优先级规则。
    • 如果当前字符是 */,并且栈顶字符是 */,则同样返回1。
    • 如果字符满足规则,则返回0。
  5. 主函数 main

    • 定义了一个字符数组 ch 用于存储输入的字符串,以及一个 cnt 类型的变量 leng 用于栈操作。
    • 使用 gets 函数读取一个字符串。注意:gets 函数是不安全的,应该使用 fgets 函数代替。
  6. 处理输入字符串

    • 遍历字符串 ch,对于字母字符,直接打印。
    • 对于运算符和括号,根据以下规则处理:
      • 如果是右括号 ),则打印栈中所有字符直到左括号 (,并减少栈顶索引。
      • 如果是左括号 ( 或者当前运算符优先级高于或等于栈顶运算符,则将当前运算符压栈。
      • 如果当前运算符优先级低于栈顶运算符,则打印栈顶运算符,并减少栈顶索引,直到满足优先级规则或栈为空,然后将当前运算符压栈。
  7. 打印栈中剩余字符

    • 循环直到栈为空,打印栈中剩余的所有字符。
  8. 程序结束

    • 返回0,表示程序正常结束。

代码逻辑分析

  • 这段代码模拟了一个简单的表达式求值器,它考虑了基本的运算符优先级和括号匹配。
  • 它使用了一个栈来存储运算符,并根据运算符的优先级规则来决定何时打印它们。

潜在问题

  • 使用 gets 函数可能导致缓冲区溢出。
  • 代码没有处理空格和数字字符,可能需要扩展以支持完整的表达式求值。

改进建议

  • 替换 gets 函数为 fgets,并添加对输入长度的检查。
  • 扩展代码以支持数字的处理和更复杂的表达式求值。
  • 考虑增加对错误输入的检查和处理,例如不匹配的括号或非法字符。

部分实现

cnt结构体定义了一个栈,包含一个字符数组L和一个整型top` 用于表示栈顶位置。

typedef struct cnt
{
    char L[max];
    int top;
}cnt;

2.判断当前字符 ch 和栈顶字符 ch2 是否满足运算符优先级的规则。

int num(char ch,char ch2)
{
   int flag = 1;
   if( ch2 == '+' || ch2== '-' )
      { if( ch == '+' || ch == '-' || ch == '*' || ch == '/')  
      { flag = 0; return 1; }
       }
   if( ch2 == '/' || ch2== '*' )
       { if( ch == '*' || ch == '/')  { flag = 0; return 1; } }
   if( flag ) return 0;

}

3.处理输入字符串

for(j=0;ch[j]!='\0';j++)
  {
      if((ch[j]>='A'&&ch[j]<='Z')||(ch[j]>='a')&&ch[j]<='z'){printf("%c",ch[j]);}
      else if(ch[j]=='+'||ch[j]=='-'||ch[j]=='*'||ch[j]=='/'||ch[j]=='('||ch[j]==')')
      {
          if(ch[j]==')')
          {
              while(leng.L[leng.top]!='(')
              {printf("%c",leng.L[leng.top]);leng.top--;}
              leng.top--;
          }
          else
          {
               
              if(leng.top==-1||(num(leng.L[leng.top],ch[j])==0)||ch[j]=='(')
              {leng.top++;leng.L[leng.top]=ch[j];}
             else if(num(leng.L[leng.top],ch[j])==1)
          {
              while(num(leng.L[leng.top],ch[j])==1&&leng.top!=-1)
              {printf("%c",leng.L[leng.top]);leng.top--;}
              leng.top=leng.top+1;
              leng.L[leng.top]=ch[j];               
          }           
          }
      }
  }
  while(leng.top!=-1)
  {
      printf("%c",leng.L[leng.top]);
      leng.top--;
  }

AC代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define max 300
 
typedef struct cnt
{
    char L[max];
    int top;
}cnt;
int num(char ch,char ch2)
{
    int flag = 1;
    if( ch2 == '+' || ch2== '-' )
       { if( ch == '+' || ch == '-' || ch == '*' || ch == '/')  
       { flag = 0; return 1; }
        }
    if( ch2 == '/' || ch2== '*' )
        { if( ch == '*' || ch == '/')  { flag = 0; return 1; } }
    if( flag ) return 0;
 
}
int main()
{
    char ch[max];
    int i=0,j;
    cnt leng;
    leng.top=-1;
     
    gets(ch);
    for(j=0;ch[j]!='\0';j++)
    {
        if((ch[j]>='A'&&ch[j]<='Z')||(ch[j]>='a')&&ch[j]<='z'){printf("%c",ch[j]);}
        else if(ch[j]=='+'||ch[j]=='-'||ch[j]=='*'||ch[j]=='/'||ch[j]=='('||ch[j]==')')
        {
            if(ch[j]==')')
            {
                while(leng.L[leng.top]!='(')
                {printf("%c",leng.L[leng.top]);leng.top--;}
                leng.top--;
            }
            else
            {
                 
                if(leng.top==-1||(num(leng.L[leng.top],ch[j])==0)||ch[j]=='(')
                {leng.top++;leng.L[leng.top]=ch[j];}
               else if(num(leng.L[leng.top],ch[j])==1)
            {
                while(num(leng.L[leng.top],ch[j])==1&&leng.top!=-1)
                {printf("%c",leng.L[leng.top]);leng.top--;}
                leng.top=leng.top+1;
                leng.L[leng.top]=ch[j];               
            }           
            }
        }
    }
    while(leng.top!=-1)
    {
        printf("%c",leng.L[leng.top]);
        leng.top--;
    }
        return 0;
}
  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值