• 表达式计算(双栈实现)


    问题:计算下列表达式
      1+2*3-4-(2-(-1))*2+4/2
    计算中包含+,-,*,/,(,),数字,负号(-)


    1
    #include <iostream> 2 #include <stack> 3 4 using namespace std; 5 6 bool isOp(string &val, int pos) { 7 if (val[pos] == '-') { 8 if (pos == 0 || (isOp(val, pos-1) && val[pos-1] != ')')) { 9 return false; 10 } 11 } 12 char c = val[pos]; 13 return (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')'); 14 } 15 16 int getPriority(char c) { 17 if (c == '(' || c == ')') 18 return 0; 19 else if (c == '+' || c == '-') 20 return 1; 21 else if (c == '*' || c == '/') 22 return 2; 23 return 0; 24 } 25 26 int getResult(int a, int b, char op) { 27 if (op == '+') 28 return a + b; 29 else if (op == '-') 30 return a - b; 31 else if (op == '*') 32 return a * b; 33 else if (op == '/') 34 return a / b; 35 return 0; 36 } 37 38 void calculate(stack<int> &data, stack<char> &op) { 39 char ch = op.top(); 40 int behind = data.top(); 41 data.pop(); 42 int before = data.top(); 43 data.pop(); 44 data.push(getResult(before, behind, ch)); 45 op.pop(); 46 } 47 48 int main() { 49 string val; 50 cin >> val; 51 int result = 0; 52 stack<int> data; 53 stack<char> op; 54 string tmp = ""; 55 for (int i = 0; i < val.length(); ++i) { 56 if (isOp(val, i) ) { 57 if (!tmp.empty()) { 58 data.push(atoi(tmp.c_str())); 59 tmp.clear(); 60 } 61 if (op.empty() || val[i] == '(') { 62 op.push(val[i]); 63 } else { 64 bool bKuoHao = false; 65 while (!op.empty() && getPriority(op.top()) >= getPriority(val[i])) { 66 if (val[i] == ')') { 67 while(!op.empty() && op.top() != '(') { 68 calculate(data, op); 69 } 70 op.pop(); 71 bKuoHao = true; 72 break; 73 } else { 74 calculate(data, op); 75 } 76 } 77 if (!bKuoHao) 78 op.push(val[i]); 79 } 80 } else { 81 tmp += val[i]; 82 if (i == val.length() - 1) { 83 data.push(atoi(tmp.c_str())); 84 tmp.clear(); 85 } 86 } 87 } 88 while(!op.empty()) { 89 calculate(data, op); 90 } 91 cout << data.top() << endl; 92 93 return 0; 94 }

    上面的不支持浮点数的计算,所以这里再调整一下数据类型,支持double

    可计算浮点数 3.8*2.4-(2.3/1.2)

     1 #include <iostream>
     2 #include <stack>
     3 
     4 using namespace std;
     5 
     6 //判断是否是运算符
     7 bool isOp(string &val, int pos) {
     8     if (val[pos] == '-') {
     9         if (pos == 0 || (isOp(val, pos-1) && val[pos-1] != ')')) { // 判断是负号就不能当成是运算符,直接写到数字里面
    10             return false;
    11         }
    12     }
    13     char c = val[pos];
    14     return (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')');
    15 }
    16 
    17 //计算符号的优先级
    18 int getPriority(char c) {
    19     if (c == '(' || c == ')')
    20         return 0;
    21     else if (c == '+' || c == '-') 
    22         return 1;   
    23     else if (c == '*' || c == '/')
    24         return 2;
    25     return 0;
    26 }
    27 
    28 //计算函数,通过运算符实行对应的计算
    29 double getResult(double a, double b, char op) {
    30     if (op == '+')
    31         return a + b;
    32     else if (op == '-')
    33         return a - b;
    34     else if (op == '*')
    35         return a * b;
    36     else if (op == '/')
    37         return a / b;
    38     return 0;
    39 }
    40 
    41 //操作栈计算栈顶的结果并放回栈中
    42 void calculate(stack<double> &data, stack<char> &op) {
    43     char ch = op.top();
    44     double behind = data.top();
    45     data.pop();
    46     double before = data.top();
    47     data.pop();
    48     data.push(getResult(before, behind, ch));
    49     op.pop();
    50 }
    51 
    52 int main() {
    53     string val;
    54     while(cin >> val) {
    55         stack<double> data;
    56         stack<char> op;
    57         string tmp = "";
    58         for (int i = 0; i < val.length(); ++i) {
    59             if (isOp(val, i) ) { // 如果当前位置表示的是运算符
    60                 if (!tmp.empty()) { // 如果数字非空,则将数字压到数字栈中
    61                     data.push(atof(tmp.c_str()));
    62                     tmp.clear();
    63                 }
    64                 if (op.empty() || val[i] == '(') { // 符号栈空的情况下或者碰到左括号,直接压栈即可
    65                     op.push(val[i]);
    66                 } else {
    67                     bool bKuoHao = false;
    68                     while (!op.empty() && getPriority(op.top()) >= getPriority(val[i])) { // 当符号栈顶的优先级大于等于当前符号的优先级的时候,则需要先计算栈里面的值
    69                         if (val[i] == ')') { // 如果当前的符号是右括号,需要特殊处理,计算栈直到遇到左括号结束
    70                             while(!op.empty() && op.top() != '(') {
    71                                 calculate(data, op);
    72                             }
    73                             op.pop();
    74                             bKuoHao = true;
    75                             break;
    76                         } else { // 否则就是对栈顶的运算符进行计算
    77                             calculate(data, op);
    78                         }
    79                     }
    80                     if (!bKuoHao) // 括号的情况下不需要压栈
    81                         op.push(val[i]);
    82                 }
    83             } else { //非运算符及累加起来转换成数字
    84                 tmp += val[i];
    85                 if (i == val.length() - 1) { // 最后一个数字需要特殊处理主动压栈
    86                     data.push(atof(tmp.c_str()));
    87                     tmp.clear();
    88                 }
    89             }
    90         }
    91         while(!op.empty()) {
    92             calculate(data, op);
    93         }
    94         cout << data.top() << endl;
    95     }
    96     return 0;
    97 }

      

  • 相关阅读:
    淘女郎相册爬虫(Python编写)
    在 Linux 命令行中使用和执行 PHP 代码
    PHP PhantomJs中文文档(翻译)
    PHP
    PHP
    PHP
    PHP — 用PHP实现一个双向队列
    Redis — CentOS6.4安装Redis以及安装PHP客户端phpredis
    Linux
    Memcache学习笔记
  • 原文地址:https://www.cnblogs.com/zllwxm123/p/16408583.html
Copyright © 2020-2023  润新知