用自定义的栈实现算术表达式(后缀表达式)求值

用自定义的栈实现算术表达式求值

基本思想就是把中缀表达式通过栈转换为后缀表达式,然后利用后缀表达式求值。当然可以换成STL里的栈。但如果都用STL了还学什么数据结构嘛。看不懂留言。

#include <iostream>
#include <string>
using namespace std;
#define max 88
//luosansui's Sequential stack
//构建一个栈的数据类型
struct stack {
	string* m_sq = new string[max];
	int top = -1;
};
//定义操作数优先级
void priority(char singleSym, int& p) {
	switch (singleSym) {
	case '#':
		p = -1;
		break;
	case '(':
		p = 0;
		break;
	case '+':
		p = 1;
		break;
	case '-':
		p = 1;
		break;
	case '*':
		p = 2;
		break;
	case '/':
		p = 2;
		break;
	case ')':
		p = 3;
		break;
	}
}
//判断操作数优先级,并合成一个栈
void judgePriority(stack& fig, stack& sym, char singleSym, int e, int s) {
	if (e == 0) {
		//压入
		sym.m_sq[++sym.top] = singleSym;
	}
	else if (e == 3) {// 22+15*(33-27)/3
	   //弹出
		while (sym.m_sq[sym.top][0] != '(') {
			fig.m_sq[++fig.top] = sym.m_sq[sym.top--];
		}
		sym.top--;
	}
	else if (e > s) {
		//压入
		sym.m_sq[++sym.top] = singleSym;
	}
	else if (e <= s) {
		//弹出
		while (e <= s) {
			fig.m_sq[++fig.top] = sym.m_sq[sym.top--];
			priority(sym.m_sq[sym.top][0], s);
		}
		//压入
		sym.m_sq[++sym.top] = singleSym;
	}
}
//最后弹出所有的
void lastJudgePriority(stack& fig, stack& sym) {
	while (sym.m_sq[sym.top][0] != '#') {
		//弹出
		fig.m_sq[++fig.top] = sym.m_sq[sym.top--];
	}
}
//判断是否为操作符
bool IsSymbol(char isSym) {
	switch (isSym) {
	case '+':
	case '-':
	case '*':
	case '/':
	case '(':
	case ')':
		return true;
	default:
		return false;
	}
}
//转换为后缀表达式
stack& conversion(string& exp, stack& sym, stack& fig) {
	//分解算术表达式
	for (int i = 0; i < (int)exp.length(); i++) {
		//将数字压入栈
		if (!IsSymbol(exp[i])) {
			//将第一个数字压入fig栈
			++fig.top;
			fig.m_sq[fig.top] = exp[i];
			//判断下一个是否为字符型数字	
			while (exp[i + 1] != NULL && !IsSymbol(exp[i + 1])) {
				fig.m_sq[fig.top] += exp[i + 1];
				i++;
			}
		}
		else {
			int a, b;
			//定义&判断操作数优先级
			priority(exp[i], a);
			priority(sym.m_sq[sym.top][0], b);
			judgePriority(fig, sym, exp[i], a, b);
		}
	}
	lastJudgePriority(fig, sym);
	delete[] sym.m_sq;
	//显示后缀表达式
	cout << "后缀表达式为:";
	for (int i = 0; i < 20; i++)
	{
		cout << fig.m_sq[i] << " ";
	}
	cout << endl;
	//返回结果
	return fig;
}
//计算
double cal(string a, string b, char c) {
	double x = atof(a.c_str());
	double y = atof(b.c_str());
	switch (c) {
	case '+':
		y = x + y;
		break;
	case '-':
		y = x - y;
		break;
	case '*':
		y = x * y;
		break;
	case '/':
		y = x / y;
		break;
	}
	return y;
}
//提取应运算的运算数与操作符
void calculate(stack& sta) {
	string a, b;
	for (int i = 0; i <= sta.top; i++) {
		if (IsSymbol(sta.m_sq[i][0])) {
			b = sta.m_sq[i - 1];
			sta.m_sq[i - 1] = "";
			for (int j = i - 2; j > -1; j--) {
				if (!IsSymbol(sta.m_sq[j][0])&& sta.m_sq[j]!= "") {
					a = sta.m_sq[j];
					sta.m_sq[j] = "";
					break;
				}
			}
			sta.m_sq[i] = to_string(cal(a, b, sta.m_sq[i][0]));
		}
	}
	double lss = atof(sta.m_sq[sta.top].c_str());
	cout << lss << endl;
	delete[] sta.m_sq;
}
//过滤用户输入的表达式中的空格
void filter(string& exp) {
	int num = 0;
	for (int i = 0; i < (int)exp.length() -1; i++){
		for (int j = 0; j < (int)exp.length() - i - 1; j++) {
			if (exp[j] == ' ') {
				exp[j] = exp[j + 1];
				exp[j + 1] = ' ';
			}
		}
	}
	for (int i = (int)exp.length(); i > -1; i--){
		if (exp[i] == ' ') {
			num++;
		}
	}
		exp = exp.substr(0,exp.length() - num);
}
int main() {
	//提示用户输入算术表达式
	string expression;
	cout << "请输入算术表达式" << endl;
	//cin >> exp;
	getline(cin, expression);
	//过滤
	filter(expression);
	//构建两个栈,一个存放符号,一个存放数字
	stack symbol, figures;
	symbol.m_sq[0] = '#';
	symbol.top = 0;
	//计算
	stack sta = conversion(expression, symbol, figures);
	calculate(sta);
	system("pause");
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值