栈的使用:该代码是将中缀表达式转为后缀表达式,并计算后缀表达式。此只支持简单的整形。
#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;
}