后缀式求值(暂有错误)

理解题意:

我们人类习惯于书写“中缀式”,如 3 + 5 * 2 ,其值为13。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)

而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是: 3 5 2 * +

现在,请对输入的后缀式进行求值。为了简化输入处理和运算,运算数(操作数)不超过300个且均为1位正整数,运算符(操作符)仅有+ - * /(加减乘除)四种,运算数和运算符之间没有空格间隔,且题目保证运算的中间结果和最终结果都在整型范围内

但是注意,题目输入的后缀式可能错误,例如:

  • 1234+- 错误,缺少运算符
  • 123+-* 错误,缺少运算数
  • 122-/ 错误,除数为0

题目保证以上三种错误不会同时发生。

输入格式:

第一行给出一个不超过10的正整数k;

接下来k行,每行给出一个后缀式,后缀式的格式如上文所描述,1位操作数且无空格间隔。

输出格式:

输出有k行,对于所输入的每个后缀式,判断是否正确(可求值),并在一行里输出:

  • 如果后缀式无误、可求值,输出结果
  • 如果发现除数为0,则输出 Division By Zero!
  • 如果发现其它错误,则输出 Expression Error!

输入样例1:

2
1234+-*
123+4-*

输出样例1:

-5
1

输入样例2:

2
12+
1234+-

输出样例2:

3
Expression Error!

输入样例3:

2
2222+-*
22+-*

输出样例3:

-4
Expression Error!

输入样例4:

1
2222-/+

输出样例4:

Division By Zero!

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

栈限制

8192 KB


代码如下:

#include <iostream>
using namespace std;
#define M 20
#define e -300
class stack{
private:
    int* p;
    int top;
    int size;
    bool isempty(){ return top==-1; }
public:
    stack(){
        p = new int[M];
        top = -1;
        size = M;
    }
   void push(int t) { p[++top]=t; }
   int pop(){ return (isempty()==false)? p[top--] : e;}
   bool isgo(){ return top>=1; }        //判断栈中的元素个数是否>=2
   ~stack(){ delete[] p; p=nullptr; }
};
inline void test(char a[]){
   stack pa;                          //创建栈对象
   int j;
   for(j=0;a[j]!='\0';j++){           //遍历字符数组,进行相应操作
           if(isdigit(a[j])){
               int t=a[j]-'0';
               pa.push(t);             //数字一律入栈
           }else{
               if(pa.isgo()){
                   int x=pa.pop();      //连取2个数,进行运算
                   int y=pa.pop();
                   int s;               //计算结果
               switch(a[j]){
                    case '+': s=y+x; break;
                    case '-': s=y-x; break;
                    case '*': s=y*x; break;
                    case '/':                         //swicth case,计算 
                       if(x==0){
                      cout<<"Division By Zero!\n";
                      return;
                       }
                       s=y/x;
                       break;
                   default: cout<<"Expression Error!\n"; return;
               }
                   pa.push(s);                  //计算结果入栈
               }else{
                   cout<<"Expression Error!\n";
                   return;
               }
           }
       }
         if(pa.isgo()||j==1){     //如果栈中元素>=2,说明缺少运算符
             cout<<"Expression Error!\n";
             return;
         }
        cout<<pa.pop()<<endl;     //如果计算成功,输出这一轮的结果
}
int main(){
     int n;
     cin>>n;
     char a[n][M+1]; 
     for(int i=0;i<n;i++) cin>>a[i];
     for(int i=0;i<n;i++) test(a[i]);
     return 0;
}


------------------------ 希望有人可以指出我的错误!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后缀表达也称为逆波兰表达,它是一种不包含括号的算术表达后缀表达运算符在后面,每个运算符的操作数都在它前面。例如,后缀表达 "3 4 +" 等价于中缀表达 "3 + 4"。 后缀表达求值可以使用栈来实现。具体步骤如下: 1. 从左到右扫描后缀表达。 2. 如果是操作数,将其压入栈中。 3. 如果是运算符,弹出栈顶的两个操作数,进行运算,并将结果压入栈中。 4. 重复步骤 2 和步骤 3,直到表达的最右端。 5. 最后,栈中只剩下一个元素,即为表达的值。 以下是使用 C 语言实现后缀表达求值的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_STACK_SIZE 100 typedef struct { int top; int stack[MAX_STACK_SIZE]; } Stack; void push(Stack *s, int data) { if (s->top >= MAX_STACK_SIZE) { printf("Stack overflow\n"); exit(EXIT_FAILURE); } s->stack[++s->top] = data; } int pop(Stack *s) { if (s->top < 0) { printf("Stack underflow\n"); exit(EXIT_FAILURE); } return s->stack[s->top--]; } int evaluatePostfix(char *expr) { Stack s; s.top = -1; int i, op1, op2, result; for (i = 0; expr[i] != '\0'; i++) { if (isdigit(expr[i])) { push(&s, expr[i] - '0'); } else { op2 = pop(&s); op1 = pop(&s); switch (expr[i]) { case '+': result = op1 + op2; break; case '-': result = op1 - op2; break; case '*': result = op1 * op2; break; case '/': if (op2 == 0) { printf("Division by zero\n"); exit(EXIT_FAILURE); } result = op1 / op2; break; default: printf("Invalid operator\n"); exit(EXIT_FAILURE); } push(&s, result); } } result = pop(&s); if (s.top >= 0) { printf("Invalid expression\n"); exit(EXIT_FAILURE); } return result; } int main() { char expr[MAX_STACK_SIZE]; printf("Enter postfix expression: "); fgets(expr, MAX_STACK_SIZE, stdin); int result = evaluatePostfix(expr); printf("Result = %d\n", result); return 0; } ``` 在这个示例中,我们使用了一个 `Stack` 结构体来实现栈的功能。`push` 函数用于将元素压入栈中,`pop` 函数用于弹出栈顶元素。`evaluatePostfix` 函数用于计算后缀表达的值。在函数中,我们遍历后缀表达的每个字符,如果是数字,就将其转化为整数并压入栈中;如果是运算符,就弹出栈顶的两个操作数进行运算,并将结果压入栈中;最后,弹出栈顶元素作为表达的值,并检查栈是否为空。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值