#ifndef _EXPCAL_H_
#define _EXPCAL_H
//视频讲解链接
//http://study.163.com/course/courseLearn.htm?courseId=1367011#/learn/video?lessonId=1738301&courseId=1367011
#include<iostream>
#include<stack>
using namespace std;
class Expression{
public:
int exp_cal(char *expression){
char *str = expression;
while (*str != '\0'){
//数字直接入栈
if ((*str) >= '0' && (*str) <= '9'){//易出错:如果数字是多位数,此时不可以直接入栈
int tmp = (*str) - '0';
++str;
while (*str != '\0' && (*str) >= '0' && (*str) <= '9'){//判断是否为多位数
tmp = tmp * 10 + ((*str) - '0');
++str;
}
numStack.push(tmp);
continue;//省去后序else if的判断
}
//操作符:
//1:如栈为空,直接入栈
//2:栈不空:栈顶操作符优先级 >= 当前操作符,计算表达式值(数字栈出栈两个数,操作符栈出栈一个操作符)
// < 直接入栈
else if (isOperator(*str)){
if (operatorStack.empty() || *str == '('){//栈为空或者遇到左括号直接入栈
operatorStack.push(*str);
++str;
}
else if (*str == ')'){//遇到右括号,进行出栈操作,直到遇到左括号
do{
int rightOperNum = numStack.top();//首先出栈的是右操作数
numStack.pop();
int leftOperNum = numStack.top();
numStack.pop();
char oper = operatorStack.top();
operatorStack.pop();
int sum = cal(leftOperNum, rightOperNum, oper);
numStack.push(sum);
} while (operatorStack.top() != '(');
operatorStack.pop();//“(”出栈
++str;//略过“)”
}
else if (getPriority(operatorStack.top()) >= getPriority(*str)){//栈顶操作符优先级 >= 当前操作符,计算表达式值
int rightOperNum = numStack.top();//首先出栈的是右操作数
numStack.pop();
int leftOperNum = numStack.top();
numStack.pop();
char oper = operatorStack.top();
operatorStack.pop();
int sum = cal(leftOperNum, rightOperNum, oper);
numStack.push(sum);
}
else{//栈顶操作符优先级 < 当前操作符,直接入栈
operatorStack.push(*str);
++str;
}
}
else{//非合法字符略过
++str;
}
}//while
//字符串遍历完毕,求栈中最终表达式的值
while (!operatorStack.empty()){
int rightOperNum = numStack.top();//首先出栈的是右操作数
numStack.pop();
int leftOperNum = numStack.top();
numStack.pop();
char oper = operatorStack.top();
operatorStack.pop();
int sum = cal(leftOperNum, rightOperNum, oper);
numStack.push(sum);
}
if (numStack.size() != 1){
cout << "error" << endl;
return -1;
}
return numStack.top();//若最终元素个数不是1,表示表达式非法
}
private:
int cal(int left, int right, char oper){
switch (oper){
case '+':
return left + right;
break;
case '-':
return left - right;
break;
case '*':
return left * right;
break;
case '/':
return left / right;
break;
}
}
int getPriority(char c){
switch (c){
case '+':
case '-':
return 1;
break;
case '*':
case '/':
return 2;
break;
default:
return -1;
break;
}
}
bool isOperator(char c){//判断是否为合法操作符
switch (c){
case '+':
return true;
break;
case '-':
return true;
break;
case '*':
return true;
break;
case '/':
return true;
break;
case '(':
return true;
break;
case ')':
return true;
break;
default:
return false;
}
}
private:
stack<int> numStack; //数字栈
stack<char> operatorStack; //操作符栈
};
#endif
main.cpp
#include"expCal.h"
int main()
{
Expression exp;
char *str = "1+2*(30+4)*(5/2)";
cout << exp.exp_cal(str) << endl;;
system("pause");
return 0;
}