数据结构-多项式计算器(将中缀表达式转化为后缀表达式实现)

  数据结构习题-多项式计算器(将中缀表达式转化为后缀表达式实现)

  我们把平时所用的标准四则运算表达式,即“9+(3-1)×3+10÷2”叫做中缀表达式。“9 3 1 - 3 × + 10 2 ÷ +”叫做后缀表达式。

  后缀表达式的计算规则为:有一个栈,先从左到右遍历表达式的每个数字和运算符,遇到数字就进栈,遇到符号就将处于栈顶两个数字出栈,进行运算,运算结果出栈,一直到最终获得结果。

  中缀表达式“9+(3-1)×3+10÷2”转化为后缀表达式“9 3 1 - 3 × + 10 2 ÷ +”

  规则为:从左到右遍历中缀表达式的每个数字与符号,如果是数字则直接输出,即成为后缀表达式的一部分,如果是符号则分两种情况,是右括号则将栈内左括号(含左括号)的元素出栈,不是右括号则判断二者的优先级,若优先级低于栈顶元素,则将不低于当前符号优先级的栈顶符号元素依次出栈并输出,最后将当前符号进栈,一直到完成对中缀表达式的遍历为止。

  以下为实现代码:

  1 #ifndef CAL_HEAD_H_
  2 #define CAL_HEAD_H_
  3 
  4 
  5 #include <iostream>
  6 #include<string>
  7 #include<stack>
  8 #include<stdlib.h>
  9 using namespace std;
 10 
 11 class Calculater
 12 {
 13 private:
 14     string str;             //  存放中缀表达式的字符串
 15     string temp_str[100];
 16     stack<double> suffix;   // 存放后缀表达式的栈
 17     stack<char> temp;      // 临时存放运算符的栈
 18     public:
 19     Calculater(string InfixExp = NULL):str(InfixExp){}   // 构造函数
 20     ~Calculater(){}
 21 
 22     bool infixToSuffix();   // 将中缀表达式转化为后缀表达式
 23     double calsuffix();       // 计算后缀表达式
 24     double cal(double num1,double num2, const char* op);  // 计算
 25 };
 26 
 27 bool Calculater::infixToSuffix()
 28 {
 29     char temp_2 = ' ';    // 存放临时元素
 30     int sign = 0;
 31     for (int i = 0; i < str.length(); ++i)
 32     {
 33         // 如果是数字,则直接压入临时字符串
 34         while(str[i]>='0' && str[i]<='9')
 35         {
 36             temp_str[sign] += str[i++];
 37             //suffix.push(str[i]);
 38         }
 39         if (temp_str[sign] != "")
 40         {
 41             sign++;
 42         }
 43         // 如果是(或者加减乘除运算符,则压入临时栈
 44         if (str[i]=='(' ||str[i]=='+' ||
 45                 str[i]=='-' || str[i]=='/' || 
 46                 str[i]=='*' || str[i]==')')
 47         {
 48             
 49             // 如果临时栈为空,则元素直接入栈
 50             if (temp.empty())
 51             {
 52                 //temp_str += str[i];
 53                 temp.push(str[i]);
 54             }
 55             else
 56             { 
 57                 // 如果不为空,若栈顶元素为(,则元素直接入栈
 58                 temp_2 = temp.top();
 59                 //temp.top(temp_2);
 60                 if (str[i] == '(')
 61                 {
 62                     //temp_str += str[i];
 63                     temp.push(str[i]);
 64                 }
 65                 else
 66                 {
 67                     // 若栈顶元素不为‘(’,是右括号或优先级低于栈顶元素,则栈顶元素依次出栈并输出
 68                     if (str[i] == ')')
 69                     {
 70                         temp_2 = temp.top();  // 返回栈顶元素
 71                         temp.pop();           // 删除栈顶元素
 72                         while(temp_2 != '(')
 73                         {
 74                             temp_str[sign++] = temp_2;
 75                             //suffix.push(temp_2); // 将取出的运算符压入临时字符串
 76                             temp_2 = temp.top();  // 返回栈顶元素
 77                             temp.pop();           // 删除栈顶元素
 78                         }
 79                         //temp.push(str[i]);
 80                         temp_2 = NULL;
 81                     }
 82                     else if ((temp_2=='*'||temp_2=='/') && (str[i]=='+'||str[i]=='-'))
 83                     {
 84                         
 85                         while(temp_2 != '(')
 86                         {
 87                             temp_str[sign++] = temp_2;
 88                             //suffix.push(temp_2); // 将取出的运算符压入临时字符串
 89                             temp.pop();    // 再取出临时栈的栈顶元素
 90                             temp_2 = temp.top();
 91                         }
 92                         temp.push(str[i]);   // 将当前运算符入栈                        
 93                     }
 94                     else 
 95                     {
 96                         temp.push(str[i]);   // 将当前运算符入栈
 97                     }
 98                 }
 99             }
100         }
101         else
102         {
103             return false;
104         }
105     }
106     // 遍历整个运算式后 ,如果临时栈不为空,则元素出栈入临时字符串
107     while (!temp.empty())
108     {
109         temp_2 = temp.top();  // 返回栈顶元素
110         temp.pop();           // 删除栈顶元素
111         //suffix.push(temp_2);
112         temp_str[sign++] = temp_2;
113     }
114 }
115 
116 double Calculater::cal(double num1 , double num2 ,const char* op)
117 {
118     switch(op[0])
119     {
120     case '+':
121             return num1 + num2;
122     case '-':
123              return num1 - num2;
124     case '*':
125              return num1 * num2;
126     case '/':
127     {
128         if (num2 == 0)
129         {
130             cout<<"ERROR!"<<endl;
131         }
132         return num1;
133     }
134     default:
135         cout<<"ERROR!"<<endl;
136     }
137 }
138 
139 double Calculater::calsuffix()
140 {
141     double num1, num2;
142     for (int i = 0; temp_str[i]!=""; ++i)
143     {
144         if (temp_str[i]!="+" && temp_str[i]!="-" &&
145             temp_str[i]!="*" && temp_str[i]!="/")
146         {
147             //cout<<temp_str[i]<<endl;
148 
149             num1 = atof(temp_str[i].c_str());
150 
151             //cout<<num1<<endl;
152             suffix.push(num1);
153         }
154         else
155         {
156             num2 = suffix.top();
157             suffix.pop();
158             num1 = suffix.top();
159             suffix.pop();
160             num1 = cal(num1, num2, temp_str[i].c_str());
161             suffix.push(num1);
162         }
163     }
164     num1 = suffix.top();
165     
166     
167 
168     return num1;
169 }
170 
171 #endif

 

  该头文件只是简单实现了表达式的转化过程,没有报错系统。学报错系统时,可以直接从中缀表达式入手或者从将中缀表达式转化后缀表达式的遍历运算符的过程中入手。

 

posted on 2012-10-24 21:07  LitLeo  阅读(554)  评论(0编辑  收藏  举报

导航