zoukankan      html  css  js  c++  java
  • 3-6 中缀表达式转换成后缀表达式, 后缀表达式的计算

    第一种方法的逻辑是我比较理得清的

    法一:

    midS是存放中缀表达式的字符串,字符之间没有空格,suffiexS是存放后缀表达式的字符串,数字和字符之间都有空格

    思路:

    1.如果midS[i]是'(',直接压栈
    2.如果是数字, 把完整数字复制到到midS中后加一个空格,读取完数字后要判断此时的midS[i]是否是'',如果是的话,break结束循环
    3.如果是')',不停弹栈,把弹栈后的字符存到suffiexS中,加空格,注意要更新ch中所存栈顶元素的值,等遇到栈顶为'('时,停止弹栈,把'('出栈
    4.如果栈顶字符优先级小于midS[i]或者栈为空,那么midS[i]直接进栈
    5.如果栈顶字符优先级大于等于midS[i],一直弹出栈顶元素到suffiexS中(直到栈顶字符优先级小于midS[i]或者栈为空),每次存字符之后都要加空格,循环中注意更新ch中所存栈顶元素的值,'('的优先级最低,所以无论如何都不会在此比较下被弹出
    6.退出循环后,判断栈是否为空,如果不为空的话,一直弹栈,将字符存入后缀表达式的字符串,加空格

      1 #include "SqStack.h"
      2 #include <cctype>
      3 
      4 double caculate(double a, char ch, double b)
      5 {
      6     switch (ch)
      7     {
      8     case '+':    return a + b;
      9     case '-':   return a - b;
     10     case '*':   return a * b;
     11     case '/':    return a / b;
     12     }
     13     return 0;
     14 }
     15 
     16 int get_priority(char ch)
     17 {
     18     int priority = 0;
     19     switch (ch)
     20     {
     21     case '+':
     22     case '-':
     23         priority = 1;
     24         break;
     25     case '*':
     26     case '/':
     27         priority = 2;
     28         break;
     29     case '(':
     30         priority = 0;
     31         break;
     32     }
     33     return priority;
     34 }
     35 
     36 /*中缀表达式转后缀表达式*/
     37 void transform(char* suffiexS, char* midS)
     38 {
     39     int i = 0;
     40     int cnt = 0;        //作为后缀表达式的字符栈的下标
     41     SqStack<char> Stack;
     42     char ch;
     43     cout << midS << endl;
     44     for (i = 0; midS[i] != ''; ++i)
     45     {
     46         /*先把'('和 '数字的情况考虑了*/
     47         if (midS[i] == '(')            //如果是'('则直接进栈
     48         {
     49             Stack.push(midS[i]);
     50             continue;
     51         }
     52 
     53         if (isdigit(midS[i]))
     54         {
     55             while (isdigit(midS[i]) && midS[i] != '')            //如果是数字,则整个赋值到midS中
     56                 suffiexS[cnt++] = midS[i++];
     57     
     58             suffiexS[cnt++] = ' ';                    //在数字后面加一个空格
     59             if (midS[i] == '')
     60                 break;
     61         }
     62         if (!Stack.IsEmpty())
     63             Stack.getTop(ch);
     64         if (midS[i] == ')')
     65         {
     66             Stack.getTop(ch);
     67             while (ch != '(')
     68             {
     69                 Stack.pop(ch);
     70                 suffiexS[cnt++] = ch;
     71                 suffiexS[cnt++] = ' ';
     72                 Stack.getTop(ch);
     73             }
     74             Stack.pop(ch);            //将'('弹出,但不存储
     75             continue;
     76         }
     77 
     78         //如果栈顶字符优先级大于等于midS[i]且栈不为空,弹出栈顶元素到midS中,加空格
     79         
     80         else if ((Stack.IsEmpty() || get_priority(ch) < get_priority(midS[i]))) 81         {
     82             Stack.push(midS[i]);
     83         }
     84             
     85         else if (get_priority(ch) >= get_priority(midS[i]))
     86         {
     87             while (get_priority(ch) >= get_priority(midS[i]) && !Stack.IsEmpty())
     88             {
     89                 Stack.pop(ch);
     90                 suffiexS[cnt++] = ch;
     91                 suffiexS[cnt++] = ' ';
     92                 Stack.getTop(ch);
     93             }
     94             Stack.push(midS[i]);            //把midS[i]入栈
     95         }
     96     }
     97     while (!Stack.IsEmpty())
     98     {
     99         Stack.pop(ch);
    100         suffiexS[cnt++] = ch;
    101     }
    102     
    103     suffiexS[cnt] = '';            //在后缀表达式末尾加上空字符
    104     cout << suffiexS << endl;
    105 }

    输入1:

     2+3*(7-4)+8/4#
    输入2:
     ((2+3)*4-(8+2))/5#
     
    第二种方法:
     1 #include <iostream>
     2 #include <cctype>
     3 #include <stack>
     4 using namespace std;
     5 
     6 int getPriority(char ch)
     7 {
     8     int priority = 0;
     9     switch(ch)
    10     {
    11         case '+':
    12             priority = 1;
    13             break;
    14         case '-':
    15             priority = 1;
    16             break;
    17         case '*':
    18             priority = 2;
    19             break;
    20         case '/':
    21             priority = 2;
    22             break;
    23         case '(':
    24             priority = 3;
    25             break;
    26         default:
    27             priority = 0;
    28             break;
    29     }
    30     return priority;
    31 }
    32 
    33 
    34 int main()
    35 {
    36     std::stack<char> S;
    37     char ch;
    38     cin >> ch;
    39     while (ch != '#')
    40     {
    41         while (isdigit(ch))
    42         {
    43             cout << ch;
    44             cin >> ch;
    45             if(!isdigit(ch))        //ch 不是数字且不是'#', 表示完成了一个整型数据的输入,此时打印一个空格
    46                 cout << " ";
    47             
    48 
    49         }
    50         if (ch == '#')
    51             break;
    52         if (ch == ')')                    //如果读入的字符是')',那么当栈顶元素不是‘(’时,一直输出栈顶元素
    53         {
    54             while (S.top() != '(')
    55             {
    56                 cout  << S.top()<< " ";
    57                 S.pop();
    58             }
    59             S.pop();
    60         }
    61         else     //正常情况,将ch和栈顶字符比较优先级
    62         {
    63             while (!S.empty() && S.top() != '(' && getPriority(S.top()) >= getPriority(ch))
    64             {
    65                 cout << S.top()<< " " ;
    66                 S.pop();
    67             }
    68             S.push(ch);
    69 
    70         }cin >> ch;
    71     }
    72 
    73     while (!S.empty())
    74     {
    75         cout << S.top();
    76         S.pop();
    77         if (!S.empty())
    78             cout << " ";
    79     }
    80 
    81     return 0;
    82 }

     

    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludextgmath.h(214): warning C4602: #pragma pop_macro:“new”该标识符前面没有 #pragma push_macro
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludextgmath.h(215): warning C4193: #pragma warning(pop) : 没有匹配的“#pragma warning(push)”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludextgmath.h(216): warning C4161: #pragma pack(pop...) : 出栈的比入栈的多
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(23): error C2061: 语法错误: 标识符“abs”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(23): error C2059: 语法错误:“;”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(23): error C2061: 语法错误: 标识符“acos”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(23): error C2061: 语法错误: 标识符“asin”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(24): error C2061: 语法错误: 标识符“atan”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(24): error C2059: 语法错误:“;”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(24): error C2061: 语法错误: 标识符“atan2”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(24): error C2061: 语法错误: 标识符“ceil”
    1>e:极速考拉下载目录vs2013(visual studio 2013旗舰版)vcincludecmath(25): error C2061: 语法错误: 标识符“cos”

    若是switch单词写错了,则可能会出现上述错误。

    最后是后缀表达式的计算:

     1 /*表达式求解*/
     2 double evaluation(char* suffiexS)
     3 {
     4     SqStack<int> Stack;
     5     int i = 0, num = 0;
     6     //cout << suffiexS << endl;
     7     int operand1, operand2, result;            //两个操作数和计算结果
     8     for (i = 0; suffiexS[i] != ''; ++i)
     9     {
    10         if (isdigit(suffiexS[i]))
    11         {
    12             while (isdigit(suffiexS[i]))
    13             {
    14                 num = num * 10 + suffiexS[i] - '0';
    15                 i++;
    16             }
    17             Stack.push(num);
    18             num = 0;
    19         }
    20         
    21         if (suffiexS[i] == ' ')
    22             continue;
    23         if (suffiexS[i] == '+')
    24         {
    25             Stack.pop(operand1);
    26             Stack.pop(operand2);
    27             result = operand1 + operand2;
    28             Stack.push(result);
    29 
    30         }
    31 
    32         if (suffiexS[i] == '-')
    33         {
    34             Stack.pop(operand1);
    35             Stack.pop(operand2);
    36             result = operand2 - operand1;        //后pop出来的做被减数
    37             Stack.push(result);
    38         }
    39 
    40         if (suffiexS[i] == '*')
    41         {
    42             Stack.pop(operand1);
    43             Stack.pop(operand2);
    44             result = operand1 * operand2;
    45             Stack.push(result);
    46         }
    47 
    48         if (suffiexS[i] == '/')
    49         {
    50             Stack.pop(operand1);
    51             Stack.pop(operand2);
    52             result = operand2 / operand1;            //后pop出来的做被除数
    53             Stack.push(result);
    54         }
    55         
    56     }
    57     Stack.pop(result);
    58     return result;
    59 }

    中缀表达式的输入函数:

     1 /*输入中缀表达式*/
     2 void readExpr(char *midS)
     3 {
     4     char ch;
     5     int i = 0;
     6 
     7     while (cin >> ch && ch != '#')
     8         midS[i++] = ch;
     9     midS[i] = '';
    10     
    11 }
  • 相关阅读:
    n!末尾有几个零
    NYOJ 14(会场安排)
    使用dynamic来简化反射实现,并且提高了性能。
    VB.NET 、Java 与 C# 语法对比。
    你不得不使用的XML代码生成器,那就是XmlFactory
    C# 和vb.net事件
    SQL Server 2008中的hierarchyid
    系统架构师基础到企业应用架构客户端/服务器
    Asp.Net在IIS上运行不了,就试下下面方法应该可以你的问题
    为你的博客添加几分色彩
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/9777420.html
Copyright © 2011-2022 走看看