数据结构-多项式计算器(将中缀表达式转化为后缀表达式实现)
数据结构习题-多项式计算器(将中缀表达式转化为后缀表达式实现)
我们把平时所用的标准四则运算表达式,即“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
该头文件只是简单实现了表达式的转化过程,没有报错系统。学报错系统时,可以直接从中缀表达式入手或者从将中缀表达式转化后缀表达式的遍历运算符的过程中入手。