9.6节练习

容器适配器

练习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;
}

猜你喜欢

转载自blog.csdn.net/xnnswmzdszyd/article/details/89789100
9.6