网教24. 波兰表达式

背景 

以下是几个标准的表达式: 

  • 5 * 2 + -3 
  • 5 * (2 + -3) 
  • 5 + ((-4 * -5) + (((5 + (6 - 2)) * 7 + ((4 + 2) * (3 - 1)))) 

与之等价的波兰表达式为 

  • + * 5 2 -3 
  • * 5 + 2 -3 
  • + 5 + * -4 -5 + * + 5 - 6 2 7 * + 4 2 - 3 1 

在普通的表达式中,符号是位于运算对象之间的,而在波兰表达式中,运算符号位于参与运算的对象之前。 

波兰式在计算中的价值在于它不需要使用括号,之所以如此是由于波兰式的操作符的先后顺序是明确的。 

如果我们用 P 表示波兰表达式,用 O 表示操作符,用 D 表示数字,则可以将波兰表达式定义为 P = O P P 或 P = D。 

任务 

编写程序计算波兰表达式的值。 

输入 

输入第一行是一个整数,表示输入文件中共有几个波兰式。 

以后每行一个表达式。每个表达式长度不超过 80 个字符,且每个表达式仅包含数字 (取值范围是[-10000, 10000]) 和二元操作符 + 、- 和 * 。任何表达式或子表达式的值都在 [-1000000, 1000000] 范围内。每个数字与操作符之间,至少有一个空格作为间隔。(负号是整数值的一部分,不是操作符,并且和整数值之间没有空格。) 

输出 

对每个表达式输出其值。 

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 5↵
  2. + * 5 2 -3↵
  3. * 5 + 2 -3↵
  4. + 5 + * -4 -5 + * + 5 - 6 2 7 * + 4 2 - 3 1↵
  5. + * - + 24 5 29 5 -7↵
  6. * 0 0↵
以文本方式显示
  1. 7↵
  2. -5↵
  3. 100↵
  4. -7↵
  5. 0↵
1秒 1024KB 0
题解:
类似于逆波兰表达式,也是处理字符串的题目。
基本思路就是遇到一个符号之后就把符号后面的两个数字进行加/减/乘,然后在处理完之后就把后面的几个数字往前提,从后往前遍历,直到没有符号(只剩一个数字)输出。
虽然不知道为什么,一开始有了几次RE,貌似是数组访问到了-1.我改了一下if的内容(加了一个判断,i-1>=0之类),然后就过了。所以(不只是这次,还有以后)为了防止越界还是应该在前边加一个防越界的&&。
ps:atol()函数,把字符串直接读成数据,头文件的stdlib.h,看起来还挺好用的。
#include<stdio.h> 
#include<string.h> 
#include<math.h> 
#include<stdlib.h> 
long int num[100]; 
char tmp[100]; 
int main() 
{ 
    int t; 
 scanf("%d", &t); 
   getchar(); 
 while (t--) 
    { 
      int rear1 = 0; 
     char s[100]; 
       gets(s); 
       for (int i = 0; i <strlen(s); i++) 
      { 
          if (s[i] == ' ') 
               continue; 
          else if (s[i] >= '0'&&s[i] <= '9') 
           { 
              memset(tmp, 0, sizeof(tmp)); 
               int flag = 0; 
              if (i!=0&&s[i - 1] == '-') 
                 flag = 1; 
              int index = 0; 
             while (i != strlen(s) && s[i] >= '0'&&s[i] <= '9') 
               { 
                  tmp[index] = s[i]; 
                 index++; 
                   i++; 
               } 
              num[rear1] = atol(tmp); 
                if (flag) 
                  num[rear1] = -num[rear1]; 
              rear1++; 
           } 
          else if (s[i] == '+') 
          { 
              num[rear1] = 1000001; 
              rear1++; 
           } 
          else if (s[i] == '-'&&!(s[i+1]>='0'&&s[i+1]<='9')) 
           { 
              num[rear1] = 1000002; 
              rear1++; 
           } 
          else if (s[i] == '*') 
          { 
              num[rear1] = 1000003; 
              rear1++; 
           } 
      } 
      for (int j = rear1-1; j >= 0; j--) 
      { 
          if (num[j] == 1000001) 
         { 
              num[j] = num[j + 1] + num[j + 2]; 
              for (int l = j + 1; l<rear1; l++) 
               { 
                  num[l] = num[l + 2]; 
               } 
          } 
          else if (num[j] == 1000002) 
            { 
              num[j] = num[j + 1] - num[j + 2]; 
              for (int l = j + 1; l<rear1; l++) 
               { 
                  num[l] = num[l + 2]; 
               } 
          } 
          else if (num[j] == 1000003) 
            { 
              num[j] = num[j + 1] * num[j + 2]; 
              for (int l = j + 1; l<rear1; l++) 
               { 
                  num[l] = num[l + 2]; 
               } 
          } 
      } 
      printf("%ld\n", num[0]); 
   } 
  return 0; 
}  


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值