中缀表达式转后缀表达式并求值
将中缀表达式转化为后缀表达式
string s 为原始表达式, stack S作为算术运算符栈, vector V存储后缀表达式结果
如果是算术运算符,分一下几种情况
(优先级说明:乘除的优先级,高于加减;’)'的优先级最低,‘(’的优先级最高)
如果算术运算符栈为空,直接将算术运算符入栈 S
如果栈顶元素的优先级低于算术运算符,直接入栈
如果栈顶元素的优先级高于算术运算符,栈S执行Pop操作,Pop出来的字符放入V,
直到栈顶元素的优先级低于算术运算符或者栈为空,才将操作符入栈
注意,’(’,’)‘不同于其他加减乘除运算符,遇到’(’,直接入栈(’(‘的出栈只会在遇到’)'的情况)
遇到’)’,栈执行出栈操作,直到遇到’(’, 并把其pop出来,’)'本身不入栈
最后,把字符栈S中的元素依次Pop出来,放入V中,这时候V所存储的就是转化后的后缀表达式
通过后缀表达式,求出表达式的值
比如表达式(-1.23-1.22) x 3转化为后缀表达式为“-1.23#1.22#-#3#x”(#分隔每个元素)
定义一个double栈 S
遍历后缀表达式V
如果元素为数字,直接入栈S
如果元素为操作符, 栈S, pop出两个double操作数a, b利用操作符对a,b 进行算术运算,注意如果操作符是减号应该是 b-a, 把最终结果入栈S
最后栈只会有一个double数,这个数就是最后结果,pop出来。
c++代码
#include<iostream>
#include<stack>
#include<vector>
#include<cstdlib>
#include<limits.h>
using namespace std;
bool isNum(char ch) {
if(ch >= '0' && ch <= '9') return true;
else return false;
}
bool isOperate(char ch) {
if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')')
return true;
else return false;
}
int level(char ch) {
switch(ch) {
case '(' :
return 5;
case '*' :
return 4;
case '/' :
return 4;
case '+' :
return 3;
case '-' :
return 3;
case ')':
return 2;
}
}
/*字符串转数字*/
double scd(string s) {
if(s.length() == 0) return INT_MAX;
bool flag = false;
for(int i = 0; i < s.length(); i++) {
if(i == 0 && s[i] == '-') continue;
else if(s[i] == '.' && !flag) {
if(i > 0 && isNum(s[i-1])) {
flag = true;
continue;
}
else return INT_MAX;
}
else if(isNum(s[i])) continue;
else return INT_MAX;
}
double result = atof(s.c_str());
return result;
}
/*由中缀表达式得到后缀表达式, 向量V存储结果*/
vector<string> midToPost(string s) {
stack<char> S; /*符号栈*/
vector<string> V; /*后缀表达式*/
int i = 0;
while(i < s.length()) {
if(isNum(s[i])) {
string str = "";
while(isNum(s[i]) || s[i] == '.') {
str += s[i];
i++;
}
V.push_back(str);
}
else if(isOperate(s[i])){
/*负数情况*/
if(s[i] == '-' && i > 0 && !isNum(s[i-1])) {
string str = "-"; i++;
while(isNum(s[i]) || s[i] == '.') {
str += s[i]; i++;
}
V.push_back(str);
}else{
if(S.empty()){
S.push(s[i]); i++;
}else {
int initial = level(s[i]);
if(initial == 2) {
while(level(S.top()) != 5 && !s.empty()) {
string str = "";
str += S.top();
V.push_back(str);
S.pop();
}
if(S.top() == '(') S.pop(); i++;
} else {
while(initial <= level(S.top()) && level(S.top()) != 5 && !S.empty()) {
string str = "";
str += S.top();
V.push_back(str);
S.pop();
}
S.push(s[i]); i++;
}
}
}
}
else{
cout << "表达式出错" << endl;
V.clear();
return V;
}
}
while(!S.empty()) {
string str = ""; str += S.top();
S.pop();
V.push_back(str);
}
//for(int i = 0; i < V.size(); i++) cout << V[i] << "[]";
return V;
}
/*后缀表达式得到最终结果*/
double getValue(vector<string> V) {
stack<double> S;
for(int i = 0; i < V.size(); i++) {
/*操作运算符*/
if(V[i].length() == 1 && isOperate(V[i][0])) {
double a = 0, b = 0;
if(!S.empty()) {
a = S.top(); S.pop();
}else return INT_MAX;
if(!S.empty()) {
b = S.top(); S.pop();
}else return INT_MAX;
switch(V[i][0]) {
case '+':
S.push(b+a);
break;
case '-':
S.push(b-a);
break;
case '*':
S.push(b*a);
break;
case '/':
S.push(b/a);
break;
default:
return INT_MAX;
}
}else {
if(scd(V[i]) == INT_MAX) return INT_MAX;
else S.push(scd(V[i]));
}
}
if(S.empty()) return INT_MAX;
double value = S.top();
S.pop();
return value;
}
int main() {
string s; /*输入的字符串s*/
vector<string> V; /*后缀表达式*/
cin >> s;
V = midToPost(s);
if(getValue(V) == INT_MAX) {
cout << "表达式出错" << endl;
}
else cout << getValue(V) << endl;
}