容器适配器
练习9.52:使用stack处理括号化的表达式。当你看到一个左括号,将其记录下来。当你在一个左括号之后看到一个右括号,从stack中pop对象,直至遇到右括号,将左括号也一起弹出栈。让后将一个值(括号内的运算结果)push到栈中,表示一个括号化的(子)表达式已经处理完毕,被其运算结果所替代。
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <stack>
#include <string>
#include <cstdlib>
#include <cctype>
#include <cstring>
using namespace std;
vector<string> preParse(string str) //对中缀表达式进行预处理,分离出每个token
{
//将str中的表达式拆分
vector<string> token;
//去除表达式里面的空格
string pstr;
for (string::size_type i = 0; i < str.size(); i++){
if (str[i] != ' ')
pstr += str[i];
}
//将里面的字符一个个的保存 区别是减号还是负号
for (string::size_type i = 0; i < pstr.size(); i++){
switch (pstr[i]){
case '*':
case '/':
case '+':
case '(':
case ')':{
token.push_back(pstr.substr(i,1));
break;
}
case '-':{
if (i && (isdigit(pstr[i - 1]) || pstr[i - 1] == ')')){ //是减号
token.push_back(pstr.substr(i, 1));
}
else{
token.push_back("#");
}
break;
}
default:{
string temp;
while (isdigit(pstr[i]) && i < pstr.size()){
temp += pstr[i];
++i;
}
i--;
token.push_back(temp);
break;
}
}
}
return token;
}
//优先级判断
int getPriority(char opt){
int priority;
switch (opt){
case '#': priority = 3; break;
case '*': priority = 2; break;
case '/': priority = 2; break;
case '-': priority = 1; break;
case '+': priority = 1; break;
default: priority = 0; break;
}
return priority;
}
void calculate(stack<int> &opdStack, char opt){
if (opt == '#'){
int op = opdStack.top();
int res = 0 - op;
opdStack.pop();
opdStack.push(res);
cout << "操作符:" << opt << "操作数" << op << "答案:" << res << endl;
}
else if (opt == '*'){
int op1 = opdStack.top();
opdStack.pop();
int op2 = opdStack.top();
opdStack.pop();
int res = op1 * op2;
opdStack.push(res);
cout << "操作数" << op2 << "操作符:" << opt << "操作数" << op1 << "答案:" << res << endl;
}
else if (opt == '/'){
int op1 = opdStack.top();
opdStack.pop();
int op2 = opdStack.top();
opdStack.pop();
int res = op2 / op1;
opdStack.push(res);
cout << "操作数" << op2 << "操作符:" << opt << "操作数" << op1 << "答案:" << res << endl;
}
else if (opt == '+'){
int op1 = opdStack.top();
opdStack.pop();
int op2 = opdStack.top();
opdStack.pop();
int res = op1 + op2;
opdStack.push(res);
cout << "操作数" << op2 << "操作符:" << opt << "操作数" << op1 << "答案:" << res << endl;
}
else if (opt == '-'){
int op1 = opdStack.top();
opdStack.pop();
int op2 = opdStack.top();
opdStack.pop();
int res = op2 - op1;
opdStack.push(res);
cout << "操作数" << op2 << "操作符:" << opt << "操作数" << op1 << "答案:" << res << endl;
}
}
//用两个栈,一个用来存放数值,另一个用来存放操作符
//若发现当前操作符的优先级比上一操作符的优先级低,那么就将上一操作符先计算。
int evaMidExpression(vector<string> token){
stack<int> opdStack; //存放数值
stack<char> optStack;//存放操作符
int priority_curr = 0;
int priority_top = 0;
for (vector<string>::size_type i = 0; i < token.size(); i++){
if (token[i] == "#" || token[i] == "+" || token[i] == "-" || token[i] == "*" || token[i] == "/"){
if (optStack.empty()){
optStack.push(token[i][0]);
}
else{
priority_curr = getPriority(token[i][0]);
priority_top = getPriority(optStack.top());
if (priority_top < priority_curr){
optStack.push(token[i][0]);
}
else {
while (priority_top >= priority_curr){
calculate(opdStack, optStack.top());
optStack.pop();
if (!optStack.empty())
priority_top = getPriority(optStack.top());
else break;
}
optStack.push(token[i][0]);
}
}
}
else if (token[i] == "("){
optStack.push(token[i][0]);
}
else if (token[i] == ")"){
while (optStack.top() != '('){
calculate(opdStack, optStack.top());
optStack.pop();
}
optStack.pop();
}
else{
opdStack.push(stoi(token[i]));
}
}
while (opdStack.size() != 1){
calculate(opdStack, optStack.top());
optStack.pop();
}
return opdStack.top();
}
int _tmain(int argc, _TCHAR* argv[])
{
string str = "";
vector<string> tokens = preParse(str);
int res = evaMidExpression(tokens);
return 0;
}