《数据结构实战》中缀表达式转后缀表达式----栈的应用

栈的使用:该代码是将中缀表达式转为后缀表达式,并计算后缀表达式。此只支持简单的整形。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stack>
#include <string.h>
#include <map>

std::map<char, int> mapOperatorPriority = { {'(', 0}, {'*', 1}, {'/', 1}, {'+', 2}, {'-', 3}, {')', 4} }; // 操作符优先级

// 后缀表达式 栈的应用 简单起见 只支持整形且 0-9的数字
const char* operators[] = {
	"+",
	"-",
	"*",
	"/"
};

bool isOneOfOperators(char c, int& index)
{
	for (int i = 0; i < sizeof(operators) / sizeof(operators[0]); i++)
	{
		if (c == *operators[i])
		{
			index = i;
			return true;
		}
	}
	return false;
}

bool OperatorResult(char* strExpress, int& nResult)
{
	std::stack<int> stackExpress;
	nResult = 0;
	while (*strExpress != 0)
	{
		int iSum = 0;
		int iOperatorIndex = 0;
		if (isdigit(*strExpress)) // 是数字压栈
		{
			int iDigit = *strExpress - 48; // 按照ascii码表进行计算
			stackExpress.push(iDigit);
			strExpress++;
		}
		else if (isOneOfOperators(*strExpress, iOperatorIndex))
		{
			int iLeft = stackExpress.top();
			stackExpress.pop();
			int iRight = stackExpress.top();
			stackExpress.pop();
			if (iOperatorIndex == 0) // +
			{
				iSum = (iLeft + iRight);
				stackExpress.push(iSum); // 将结果压栈
			}
			else if (iOperatorIndex == 1) // -
			{
				iSum = (iLeft - iRight);
				stackExpress.push(iSum); // 将结果压栈
			}
			else if (iOperatorIndex == 2) // *
			{
				iSum = (iLeft * iRight);
				stackExpress.push(iSum); // 将结果压栈
			}
			if (iOperatorIndex == 3) // /
			{
				iSum = (iLeft / iRight);
				stackExpress.push(iSum); // 将结果压栈
			}
			strExpress++;
		}
	}
	if (!stackExpress.empty())
	{
		nResult = stackExpress.top();
		stackExpress.pop();
	}
	return true;
}

// 将中缀表达式转为后缀表达式
bool MiddleToEndExpress(const char* strExpress, char* strResultEnd)
{
	std::stack<char> stackOperators;
	int nLen = 0;
	while (*strExpress != 0)
	{
		char c = *strExpress;
		bool bRet = isdigit(*strExpress);
		bool bAlpha = isalpha(*strExpress);
		if (bRet || bAlpha) // 是数字或者字母
		{
			nLen += sprintf(strResultEnd + nLen, "%c", *strExpress); // 输出
		}
		else // 是操作符
		{
			if (stackOperators.empty()) // 空栈 直接压栈
				stackOperators.push(*strExpress);
			else // 比较优先级
			{
				if (*strExpress == ')') // 是右括号 // 弹出所以操作符,直到遇到'('
				{
					while (stackOperators.top() != '(')
					{
						nLen += sprintf(strResultEnd + nLen, "%c", stackOperators.top());
						stackOperators.pop();
					}
					stackOperators.pop();
				}
				else // 优先级更高则直接入栈,否则弹出直到遇到优先级更高的
				{
					auto iter = mapOperatorPriority.find(*strExpress);
					auto iterStack = mapOperatorPriority.find(stackOperators.top());
					if (*iter < *iterStack) // 优先级更高 直接入栈
						stackOperators.push(*strExpress);
					else // 操作符输入到输出 直到优先级更高的 或者遇到(
					{
						while (1)
						{
							if (stackOperators.empty())
								break;
							if (stackOperators.top() == '(')
								break;
							if (*iter >= *iterStack) // 同等优先级 或优先级更低
							{
								nLen += sprintf(strResultEnd + nLen, "%c", stackOperators.top()); //输出
								stackOperators.pop();
							}
							else
								break;
						}
						stackOperators.push(*strExpress);
					}
				}
			}
		}
		strExpress++;
	}
	// 弹出栈中的所有操作符
	while (!stackOperators.empty())
	{
		nLen += sprintf(strResultEnd + nLen, "%c", stackOperators.top()); //输出
		stackOperators.pop();
	}
	return true;
}

int main()
{
	char strEndPress[128] = { 0x00 };
	MiddleToEndExpress("5+2*6+(3*1+5)*8", strEndPress);
	int nResult = 0;
	OperatorResult(strEndPress, nResult);
	return 0;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值