数据结构课设——表达式求值(c++)

文章目录

      • 中缀表达式转后缀表达式
    • 程序源文件
      • Caculate.h
      • Caculate.cpp
      • main.cpp

完成基本功能:
(1) 从文件或者键盘读入中缀表达式。
(2) 设计操作数为多位整数,操作符为加、减、乘、除、求模的中缀表达式求值算法
(3) 设计将中缀表达式转换为后缀表达式的算法
(4) 设计将中缀表达式转换为前缀表达式的算法
(5) 设计后缀表达式的求值算法
(6) 设计前缀表达式的求值算法
(7) 输出各种形式的表达式
(8) 扩充运算符集,可进行指数运算
使用说明:
(1)输入的表达式可以带等号也可不带
(2)表达式操作符之间可以有任意空格,但总体表达式不能超过50个字符
(3)只支持加、减、乘、除、求模,乘方运算
(4)程序功能之间高内聚,低耦合,方便修改

中缀表达式转后缀表达式

规则:

从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,如果是右括号或者优先级不高于栈顶符号(乘除优先于加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止

程序源文件

Caculate.h

#pragma once
#include
#include

using namespace std;

//定义运算符优先级,越大优先级越高
constexpr auto ADD = 1;
constexpr auto SUB = 1;
constexpr auto MUL = 2;
constexpr auto DIV = 2;
constexpr auto Demo = 2;	//求模取余
constexpr auto Index = 3;	//指数 例如 2^3 = 8



class Caculate {
public:

	//是否输入了表达式, 默认false
	bool is_Input = false;

	//展示菜单
	void show_Menu();

	//获取运算符优先级
	int get_Value(string operation);

	//获取简单表达式计算结果
	//a 代表操作数 1,str 代表 操作运算符,b 代表操作数 2
	// a str b : 例如 a - b, a*b
	int get_result(int a, string str, int b);
	//输入中缀表达式
	void input_Infix();

	//存储中缀表达式
	vector<string> infix_Expression;

	//存储前缀表达式
	vector<string> prefix_Expression;

	//存储后缀表达式
	vector<string> postfix_Expression;


	//由中缀表达式转成前缀表达式
	void to_Prefix();

	//由中缀表达式转成后缀表达式
	void to_Postfix();

	//前缀表达式计算求值
	void caculate_Prefix();

	//中缀表达式计算求值
	void caculate_Infix();

	//后缀表达式计算求值
	void caculate_Postfix();

	//遍历展示vector容器中元素
	void show_Vector(vector<string> expression);

	//展示表达式的各种形式
	void show_Expression();

	//退出系统
	void exit_System();
};

Caculate.cpp

#include
#include
#include
#include
#include
#include
#include
#include "Calculate.h"

using namespace std;



//退出系统
void Caculate::exit_System() {
	cout << "欢迎下次使用!:)" << endl;
	system("pause");
	exit(0);
}

//展示菜单
void Caculate::show_Menu() {
	cout << endl;
	cout << "***********************************************" << endl;
	cout << "*************** 表达式求值计算器 ***************" << endl;
	cout << "***********************************************" << endl;
	cout << "*********** >1. 输入中缀表达式   ****************" << endl;
	cout << "*********** >2. 中缀表达式求值   ****************" << endl;
	cout << "*********** >3. 前缀表达式求值   ****************" << endl;
	cout << "*********** >4. 后缀表达式求值   ****************" << endl;
	cout << "*********** >5. 表达式的各种形式 ****************" << endl;
	cout << "*********** >0. 退出系统        ****************" << endl;
	cout << "***********************************************" << endl;
	cout << "***********************************************" << endl;
	cout << endl;
}

//获取元素优先级
int Caculate::get_Value(string operation) {
	int value = 0;

	if (operation == "+") {
		value = ADD;
	}
	else if (operation == "-") {
		value = SUB;
	}
	else if (operation == "*") {
		value = MUL;
	}
	else if (operation == "/") {
		value = DIV;
	}
	else if (operation == "%") {
		value = Demo;
	}
	else if (operation == "^") {
		value = Index;
	}
	else {
		value = 0;
	}

	return value;
}

//获取简单表达式计算结果
int Caculate::get_result(int a, string str, int b) {
	int result = 0;
	if (str == "+") {
		result = a + b;
	}
	else if (str == "-") {
		result = a - b;
	}
	else if (str == "*") {
		result = a * b;
	}
	else if (str == "/") {
		result = a / b;
	}
	else if (str == "%") {
		result = a % b;
	}
	else if (str == "^") {
		result = pow(a, b);
	}
	else {
		result = 0;
	}

	return result;
}

//输入中缀表达式

void Caculate::input_Infix() {
	this->infix_Expression.clear();		//清空容器,方便接收用户接下来的输入
	system("cls");
	
	cout << "请输入你想要计算的(中缀)表达式:" << endl;
	char cha[50];			//用来接收将要输入的表达式, 最多接收50个字符	
	cin.ignore();			//cin.getline默认以换行符为结束标志,要消耗掉前面的换行符需要多调用一次即使用两次cin.getline()									
	cin.getline(cha, 50);	//或者这之前使用cin.ignore();

	string str = string(cha);				//将字符数组转成字符串
	int len = (int)str.length();		//表达式长度
	int i = 0;

	do {
		if (str[i] == '=' || str[i] == ' ') {			//当为空格或者‘=’ 的时候,就直接跳过
			i++;
		}
		else if ( str[i] < 48 || str[i] > 57) {				//当不再0-9之间,就直接保存
			string temp = "";
			temp += str[i];
			this->infix_Expression.push_back(temp);
			i++;
		}
		else {
			string str_temp = "";
			while (i < len && str[i] >= 48 &&  str[i] <= 57) {	//当在0-9之间就拼接成原来的数字,然后再保存
				str_temp += str[i];
				i++;
			}
			this->infix_Expression.push_back(str_temp);
		}
	} while (i < len);

	this->to_Prefix();			//转换成前缀表达式
	this->to_Postfix();			//转换成后缀表达式

	//更新状态
	this->is_Input = true;

	cout << "===========================" << endl;
	cout << "表达式输入成功!:)" << endl;
	cout << endl;

	system("pause");
	system("cls");
}

//转换成后缀表达式
void Caculate::to_Postfix() {

	stack<string> sta;
	for (vector<string>::iterator it = this->infix_Expression.begin(); it != this->infix_Expression.end(); it++) {
		string str = *it;
		if (str >= "0" && str <= "9") {			//若是遇到数字就直接保存
			this->postfix_Expression.push_back(str);
		}
		else if (str == "(") {			//遇到"(" 就进栈
			sta.push(str);
		}
		else if (str == ")") {			//遇到")" 就去匹配此前的 "(",栈顶元素依次出栈,并保存
			while (sta.top() != "(") {
				this->postfix_Expression.push_back(sta.top());
				sta.pop();
			}
			sta.pop();		//弹出栈顶的 ")"
		}
		else {
			while (sta.size() != 0 && get_Value(sta.top()) >= get_Value(str)) {
				this->postfix_Expression.push_back(sta.top());
				sta.pop();
			}
			sta.push(str);
		}
	}

	//如果栈中最后还有元素,一并输出保存
	while (sta.size() != 0) {
		this->postfix_Expression.push_back(sta.top());
		sta.pop();
	}

}

//转换成前缀表达式
void Caculate::to_Prefix() {

	//定义符号栈
	stack<string> sta;
	vector<string> vec = this->infix_Expression;		//定义一个vec容器来存储中缀表达式,方便接下来的操作
	//vec.reserve(vec.size());			//vec容器元素进行反转
	reverse(vec.begin(), vec.end());
	for (vector<string>::iterator it = vec.begin(); it != vec.end(); it++) {
		string str = *it;
		if (str >= "0" && str <= "9") {			//若是遇到数字就直接保存
			this->prefix_Expression.push_back(str);
		}
		else if (str == ")") {			//遇到"(" 就进栈
			sta.push(str);
		}
		else if (str == "(") {
			while (sta.size() !=0 && sta.top() != ")") {
				this->prefix_Expression.push_back(sta.top());
				sta.pop();
			}  
			sta.pop();		//将 ")"弹出符号栈
		}
		else {
			//如果当前栈顶元素为右括号‘)’,直接将操作符放入符号栈中
			if (!sta.empty() && sta.top() == ")") {
				sta.push(str);
			}
			else {
				//果当前栈顶元素的优先级大于操作数的优先级,则将栈顶元素移除,再次和判断移除后栈的栈顶元素比较优先级大小,
				//直到当前栈顶元素小于或等于操作数优先级,将操作符放入符号栈中
				while (!sta.empty() && get_Value(sta.top()) > get_Value(str)) {
					this->prefix_Expression.push_back(sta.top());
					sta.pop();
				}
				sta.push(str);
			}
			  

		}
	}

	while (!sta.empty()) {			//最后当栈不为空的时候,将栈中的元素依次移出并保存
		this->prefix_Expression.push_back(sta.top());
		sta.pop();
	}
	//this->prefix_Expression.reserve(this->prefix_Expression.size());		//翻转字符串
	reverse(this->prefix_Expression.begin(), this->prefix_Expression.end());
}

//中缀表达式求值
void Caculate::caculate_Infix() {
	//定义两个栈,一个运算符栈,一个操作数栈
	stack<string> operator_Stack;
	stack<int> number_Stack;

	for (vector<string>::iterator it = this->infix_Expression.begin(); it != this->infix_Expression.end(); it++) {
		string str = *it;
		stringstream ss;

		int num = 0;
		if (str[0] >= '0' && str[0] <= '9') {	//如果第一个字符为数字字符,则这个字符串是数字,用istringsteam 转成数字
			istringstream istr(str);			//这样就可以实现多位整数的运算
			istr >> num;
			number_Stack.push(num);
		}

		else if (str == "(") {				//如果遇到左括号,就压进运算符栈
				operator_Stack.push(str);
			}
		else if (str == ")") {							//如果遇到右括号,就去匹配运算符栈中的左括号,当不匹配的时候,操作数栈弹出两个操作数,
			while (operator_Stack.top() != "(") {		//和当前运算符栈的栈顶运算符进行运算,最后将结果保存到操作数栈
					int a = number_Stack.top();
					number_Stack.pop();
					int b = number_Stack.top();
					number_Stack.pop();
					int result = this->get_result(b, operator_Stack.top(), a);
					number_Stack.push(result);
					operator_Stack.pop();
			}
			operator_Stack.pop();		//弹出"("
		}
		else {
			if (operator_Stack.size() == 0 || operator_Stack.top() == "(") {
				operator_Stack.push(str);
			}
			else {
				while (operator_Stack.size() != 0 && get_Value(operator_Stack.top()) >= get_Value(str)) {
					int a = number_Stack.top();				//当当前运算符优先级小于等于栈顶元素优先级时,就从操作数栈弹出两个操作数
					number_Stack.pop();						//和栈顶运算符参与运算,将结果保存到操作数栈中
					int b = number_Stack.top();
					number_Stack.pop();
					int result = this->get_result(b, operator_Stack.top(), a);
					number_Stack.push(result);
					operator_Stack.pop();
				}
				operator_Stack.push(str);					//之后将当前运算符压如运算符栈
			}
		}
	}

	while (operator_Stack.size() != 0) {					//最后当运算符栈不为空的时候,再依次弹出运算
		int a = number_Stack.top();
		number_Stack.pop();
		int b = number_Stack.top();
		number_Stack.pop();
		int result = this->get_result(b, operator_Stack.top(), a);
		number_Stack.push(result);
		operator_Stack.pop();
	}

	cout << "运算结果为:" << number_Stack.top() << endl;
	number_Stack.pop();

	system("pause");
	system("cls");
}
//前缀表达式求值
void Caculate::caculate_Prefix() {
	stack<int> sta;
	vector<string> vec = this->prefix_Expression;
	reverse(vec.begin(), vec.end());
	for (vector<string>::iterator it = vec.begin(); it != vec.end(); it++) {
		string str = *it;

		int num = 0;
		if (str[0] >= '0' && str[0] <= '9') {	//如果第一个字符为数字字符,则这个字符串是数字,用istringsteam 转成数字
			istringstream istr(str);			//这样就可以实现多位整数的运算
			istr >> num;
			sta.push(num);
		}
	
		else if(sta.size() !=0) {
			//注意与后缀表达式操作数顺序的区别
			int a = sta.top();
			sta.pop();
			int b = sta.top();
			sta.pop();
			int result = this->get_result(a, str, b);
			sta.push(result);
		}
	}
	cout << "结果为:" << sta.top() << endl;
	sta.pop();

	system("pause");
	system("cls");
}

//后缀表达式求值
void Caculate::caculate_Postfix() {
	stack<int> sta;

	for (vector<string>::iterator it = this->postfix_Expression.begin(); it != this->postfix_Expression.end(); it++) {
		string str = *it;
		stringstream ss;

		int num = 0;
		if (str[0] >= '0' && str[0] <= '9') {	//如果第一个字符为数字字符,则这个字符串是数字,用istringsteam 转成数字
			istringstream istr(str);			//这样就可以实现多位整数的运算
			istr >> num;
			sta.push(num);
		}
		else {
			int a = sta.top();
			sta.pop();
			int b = sta.top();
			sta.pop();
			int result = this->get_result(b, str, a);
			sta.push(result);
		}
	}
	cout << "结果为:" << sta.top() << endl;
	sta.pop();

	system("pause");
	system("cls");

}




//遍历展示vector容器中元素
void Caculate::show_Vector(vector<string> expression) {
	
	for (vector<string>::iterator it = expression.begin(); it != expression.end(); it++) {
		cout << (string)(*it) << " ";
	}
	cout << endl;
}

//展示表达式各种形式
void Caculate::show_Expression() {
	if (this->is_Input) {
		cout << "******************前缀表达式*****************" << endl;
		this->show_Vector(this->prefix_Expression);
		cout << "******************中缀表达式*****************" << endl;
		this->show_Vector(this->infix_Expression);
		cout << "******************后缀表达式*****************" << endl;
		this->show_Vector(this->postfix_Expression);
	}
	else {
		cout << "Oops! 请先输入表达式!" << endl;
	}

	system("pause");
	system("cls");
}

main.cpp

#include
#include "Calculate.h"

using namespace std;

int main() {

	Caculate ca;
	int choice = 0;

	while (true) {
		ca.show_Menu();
		cout << "请输入你的选择:";
		cin >> choice;

		switch (choice)
		{
		case 0:
			ca.exit_System();	//退出系统
			break;
		case 1:
			ca.input_Infix();	//输入中缀表达式
			break;
			
		case 2:
			ca.caculate_Infix();	//中缀表达式求值
			break;
			
		case 3:
			ca.caculate_Prefix();	//前缀表达式求值
			break;
			
		case 4:
			ca.caculate_Postfix();	//后缀表达式求值
			break;
			
		case 5:
			system("cls");
			ca.show_Expression();	//表达式的各种形式
			break;
			
		default:
			break;
		}
	}

	system("pause");
	return 0;
}

你可能感兴趣的:(数据结构,算法,数据结构)