Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16556
  • 博文数量: 12
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-29 08:49
文章分类

全部博文(12)

文章存档

2014年(12)

分类: IT职场

2014-07-01 16:53:24

开两个栈:数据栈和符号栈,前者存储数值,后者存储操作符。
操作符优先级:+-优先级相同,*/优先级相同,后者优先级大于前者优先级。
扫描中缀表达式:
    如果是数值,则压入数据栈
    如果是符号:
        如果符号栈为空:
            直接压入符号栈
        否则:
            如果当前符号的优先级比符号栈栈顶符号的优先级高:
                直接压入符号栈
            否则:
                从数据栈取两个操作数
                从符号栈取一个符号
                计算运算结果并压入符号栈
                循环直到符号栈为空,或者当前符号优先级比符号栈栈顶符号的优先级高
                当前符号压入符号栈
    如果符号栈不为空:
        从数据栈取两个操作数
        从符号栈取一个符号
        计算运算结果并压入符号栈
    输出结果


测试地址:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stack>
  4. using namespace std;

  5. char op[256] = {0};

  6. void init()
  7. {
  8.     op['+'] = op['-'] = 1;
  9.     op['*'] = op['/'] = 2;
  10. }

  11. double calc(double x, double y, char op)
  12. {
  13.     if (op == '+') return x + y;
  14.     if (op == '-') return x - y;
  15.     if (op == '*') return x * y;
  16.     return x / y;
  17. }

  18. int main(int argc, char **argv)
  19. {
  20.     init();
  21.     stack<double> values;
  22.     stack<char> ops;
  23.     char s[210];

  24.     while (1)
  25.     {
  26.         gets(s);
  27.         int n = strlen(s);
  28.         if (n == 1 && s[0] == '0')
  29.         {
  30.             break;
  31.         }

  32.         double tmp = 0;
  33.         for (int i = 0; i < n; ++i)
  34.         {
  35.             if (s[i] >= '0' && s[i] <= '9')
  36.             {
  37.                 tmp = tmp*10 + s[i]-'0';
  38.             }
  39.             else if (s[i] == ' ')
  40.             {
  41.                 values.push(tmp);
  42.                 tmp = 0;
  43.             }
  44.             else
  45.             {
  46.                 int cur = op[s[i]];
  47.                 int pre = 0;
  48.                 if (!ops.empty())
  49.                 {
  50.                     pre = op[ops.top()];
  51.                 }
  52.                 while (cur <= pre)
  53.                 {
  54.                     double right = values.top();
  55.                     values.pop();
  56.                     double left = values.top();
  57.                     values.pop();
  58.                     char _op = ops.top();
  59.                     ops.pop();
  60.                     values.push(calc(left, right, _op));

  61.                     if (!ops.empty())
  62.                     {
  63.                         pre = op[ops.top()];
  64.                     }
  65.                     else
  66.                     {
  67.                         break;
  68.                     }
  69.                 }
  70.                 ops.push(s[i]);
  71.                 ++i;
  72.                 tmp = 0;
  73.             }
  74.         }
  75.         values.push(tmp);

  76.         while (!ops.empty())
  77.         {
  78.             double right = values.top();
  79.             values.pop();
  80.             double left = values.top();
  81.             values.pop();
  82.             char _op = ops.top();
  83.             ops.pop();
  84.             values.push(calc(left, right, _op));
  85.         }
  86.         printf("%.2f\n", values.top());
  87.     }

  88.     return 0;
  89. }
对于存在括号的情况,考虑一下括号即可:

中缀表达式转后缀表达式

算法: 可以使用栈来完成中缀表达式到后缀表达式的转换

1、栈stack[]用来存储操作符,top指向栈顶,但不存储元素,top=0表示栈为空

2、从左向右遍历中缀表达式

  a.如果遇到的是操作数num,则直接输出到后缀表达式

  b.如果遇到的是操作符op,则有几种情况:

    b.1.如果op==')',则依次弹出栈顶直到弹出'(',但'('不输出到后缀表达式

    b.2:如果op=='(',则直接入栈

    b.3:如果栈为空,则直接入栈

    b.4:如果op的优先级高于栈顶操作符的优先级,则入栈

    b.5:如果op的优先级低于或等于栈顶操作符的优先级,则依次弹出栈顶直到op的优先级高于栈顶操作符的优先级(或栈为空),再将op入栈

3、遍历完时,如果栈仍不为空,则依次弹出栈顶直到栈为空

参考:http://www.cnblogs.com/zghaobac/p/3394705.html
阅读(796) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~