表达式求值

成绩 15 开启时间 2017年10月18日 星期三 14:00
折扣 0.8 折扣时间 2017年11月8日 星期三 23:55
允许迟交 关闭时间 2018年01月8日 星期一 23:55

背景:

我们的教材中已经介绍了表达式求值的算法,现在我们将该算法的功能进行扩展,要求可以处理的运算符包括:+、-、*、/、%(整数取余)、^(乘方)、(、)。

要求:

采用算符优先算法,计算的中间结果只保留整数。

输入:

第一行为整数N。表示下面有N个表达式

从第二行起的后面N行为N个由整数构成的表达式

输出:

共N行,每行为相应表达式的计算结果。

如果判断出表达式有错误,则输出:error.

如果在计算过程中出现除数为0的情况,则输出:Divide 0.

特殊情况说明:

在表达式中,如果操作数出现负数(例如-8),则要特别注意。例如:
10加-8表示为:10+-8。
10减-8表示为:10--8。

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 4↵
  2. 2^3↵
  3. 2^0↵
  4. 2^3^2↵
  5. 2^(3-1)^(10-8)↵
以文本方式显示
  1. 8↵
  2. 1↵
  3. 512↵
  4. 16↵
1秒 64M 0
测试用例 2 以文本方式显示
  1. 11↵
  2. (2+8↵
  3. 2+8)↵
  4. 8/0↵
  5. 8/(8+5-13)↵
  6. 2^(2-5)↵
  7. 10-(80-30(/3*3+4↵
  8. 10-80-30)/3*3+4↵
  9. (2+8)(3+2)↵
  10. (2)3(8)↵
  11. 30(/3+3)+4↵
  12. 10(20-8)+2↵
以文本方式显示
  1. error.↵
  2. error.↵
  3. Divide 0.↵
  4. Divide 0.↵
  5. error.↵
  6. error.↵
  7. error.↵
  8. error.↵
  9. error.↵
  10. error.↵
  11. error.↵
1秒 64M 0
测试用例 3 以文本方式显示
  1. 2↵
  2. 10(10)↵
  3. 14*10-(10)2↵
以文本方式显示
  1. error.↵
  2. error.↵
1秒 64M 0
测试用例 5 以文本方式显示
  1. 14↵
  2. 18-32↵
  3. 18/4↵
  4. 18%3↵
  5. 10+20*4↵
  6. 10-20/4↵
  7. (18-3)*3↵
  8. 10*(10)↵
  9. (10+2)/(8-10)↵
  10. (2*3)/(5*2)↵
  11. 10-(80-30)/3*3+4↵
  12. (((2+8)*2-(2+4)/2)*2-8)*2↵
  13. (((8+2)*(4/2)))↵
  14. 10/0↵
  15. (10-80*2↵
以文本方式显示
  1. -14↵
  2. 4↵
  3. 0↵
  4. 90↵
  5. 5↵
  6. 45↵
  7. 100↵
  8. -6↵
  9. 0↵
  10. -34↵
  11. 52↵
  12. 20↵
  13. Divide 0.↵
  14. error.↵
1秒 64M 0

#include<cstdio> 
#include<string> 
#include<map> 
#include<stack> 
#include<math.h> 
#include<iostream> 
using namespace std; 
 
map<string, int> Varible; 
stack<char> Op; 
stack<int>  Opnum; 
string Instruction; 
string tmp; 
int flag; 
int GetproiIncoming(char c) 
{ 
   switch (c) 
 { 
  case('+') : return 3; 
  case('-') : return 3; 
  case('*') : return 5; 
  case('/') : return 5; 
  case('%') : return 5; 
  case('(') : return 10; 
 case('^') : return 8; 
  } 
} 
 
int GetproInstack(char c) 
{ 
   switch (c) 
 { 
  case('+') : return 4; 
  case('-') : return 4; 
  case('*') : return 6; 
  case('/') : return 6; 
  case('%') : return 6; 
  case('(') : return 1; 
  case('^') : return 7; 
  } 
} 
 
int Comput(char c, int a, int b) 
{ 
    switch (c) 
 { 
  case('+') : return a + b; 
  case('-') : return a - b; 
  case('*') : return a*b; 
    case('/') : return a / b; 
  case('%') : return a%b; 
    case('^') : return (int)pow(double(a), double(b)); 
 } 
} 
 
int Getvar(string tmp) 
{ 
  int num = 0; flag = 0; 
 int numleft = 0; int numright = 0; 
 for (int i = 0; tmp[i]; i++) 
   { 
      if (tmp[i] >= '0'&&tmp[i] <= '9') 
        { 
          if (i>0&&tmp[i - 1] == ')') 
         { 
              flag = 1; 
              return -1; 
         } 
          num = num * 10 + tmp[i] - '0'; 
     } 
       
       else if (!(tmp[i] >= '0'&&tmp[i] <= '9')) 
        { 
          if (i > 0 && tmp[i - 1] == '(' && (tmp[i] == '%' || tmp[i] == '*' || tmp[i] == '/' || tmp[i] == '^')) 
           { 
              flag = 1; return -1; 
           } 
          if (i>0&&(tmp[i - 1] >= '0'&&tmp[i - 1] <= '9')) 
          { 
              Opnum.push(num); num = 0; 
          } 
          else if (i == 0 && (tmp[i] == '+' || tmp[i] == '-') && (tmp[i+1] >= '0'&&tmp[i+1] <= '9')) 
           { 
              i++; int k = i; 
                while (tmp[k] && (tmp[k] >= '0'&&tmp[k] <= '9')) 
             { 
                  num = num * 10 + tmp[k] - '0'; k++; 
                } 
              if (tmp[i - 1] == '-') num *= -1;   i = k - 1; continue; 
           } 
          else if (i == 0 && (tmp[i] == '%' || tmp[i] == '*' || tmp[i] == '/' || tmp[i] == '^')) 
         { 
              flag = 1; 
              return -1; 
         } 
          else if (i>0 && !(tmp[i - 1] >= '0'&&tmp[i - 1] <= '9') && (tmp[i] == '+' || tmp[i] == '-') && (tmp[i + 1] >= '0'&&tmp[i + 1] <= '9')) 
          { 
              i++; int k = i; 
                while (tmp[k] && (tmp[k] >= '0'&&tmp[k] <= '9')) 
             { 
                  num = num * 10 + tmp[k] - '0'; k++; 
                } 
              if (tmp[i - 1] == '-') num *= -1;   i = k - 1; continue; 
           } 
          if (Op.empty() || tmp[i] == '(') 
           { 
              if (tmp[i] == '(') 
             { 
                  if (i > 0 && (tmp[i - 1] >= '0'&&tmp[i - 1] <= '9'||tmp[i-1]==')')) 
                   { 
                      flag = 1; 
                      return -1; 
                 } 
              } 
              Op.push(tmp[i]);  
              if (tmp[i] == '(') numleft++; 
              continue; 
          } 
          else if (tmp[i] == ')') 
            { 
              numright++; 
                if (numright > numleft) 
             { 
                  flag = 1; 
                  return -1; 
             } 
              char op; 
               while (!Op.empty() && (op = Op.top()) != '(') 
              { 
                  int b = Opnum.top(); Opnum.pop(); 
                  int a = Opnum.top(); Opnum.pop(); 
                  if (b == 0 && op == '/') 
                   { 
                      flag = 2; return -1; 
                   } 
                  else if (b < 0 && op == '^') 
                    { 
                      flag = 1; return -1; 
                   } 
                  else { Opnum.push(Comput(op, a, b)); } 
                 Op.pop(); 
              } 
              Op.pop(); 
          } 
          else 
           { 
              int Incoming = GetproiIncoming(tmp[i]); 
                int Instack; 
               char op; 
               while (!Op.empty() && (Instack = GetproInstack(Op.top())) > Incoming) 
               { 
                  op = Op.top(); 
                 int b = Opnum.top(); Opnum.pop(); 
                  int a = Opnum.top(); Opnum.pop(); 
                  if (b == 0 && op == '/') 
                   { 
                      flag = 2; return -1; 
                   } 
                  else if (b < 0 && op == '^') 
                    { 
                      flag = 1; return -1; 
                   } 
                  else { Opnum.push(Comput(op, a, b)); } 
                 Op.pop(); 
              } 
              Op.push(tmp[i]); 
           } 
      } 
  } 
  if (tmp[tmp.length() - 1] >= '0'&&tmp[tmp.length() - 1] <= '9') 
      Opnum.push(num); 
   if (!Op.empty() || !Opnum.empty()) 
 { 
 
     while (!Op.empty()) 
        { 
          char op = Op.top(); 
            if (op == '(') 
         { 
              flag = 1; 
              return -1; 
         } 
          int b = Opnum.top(); Opnum.pop(); 
          int a = Opnum.top(); Opnum.pop(); 
          if (b == 0 && op == '/') 
           { 
              flag = 2; return -1; 
           } 
          else if (b < 0 && op == '^') 
            { 
              flag = 1; return -1; 
           } 
          else { Opnum.push(Comput(op, a, b)); } 
         Op.pop(); 
      } 
      return Opnum.top(); 
    } 
  else return num; 
} 
 
int main() 
{ 
   //freopen("1.txt", "r", stdin); 
    int T; 
 scanf("%d%*c", &T); 
    while (T--) 
    { 
      while (!Op.empty()) 
            Op.pop(); 
      while (!Opnum.empty()) 
         Opnum.pop(); 
       getline(cin, Instruction); 
     int ans=Getvar(Instruction); 
       if (flag==1) 
           printf("error.\n"); 
        else if (flag == 2) 
        { 
          printf("Divide 0.\n"); 
     } 
      else 
       { 
          printf("%d\n", ans); 
       } 
  } 
  return 0; 
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水之积也不厚,则其负大舟也无力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值