C++后缀表达式计算
继续上篇文章,实现计算器简单计算的功能
上篇文章C++中缀表达式转后缀表达式已经将中缀表达式转换成后缀表达式并保存在队列q中
后缀表达式算法思想:
-
读取队列q顶端元素,并判断元素类型
(1)若是数,将数压入运算栈sum中;
(2)若是运算符,取出栈sum顶端的两个元素计算,结果压回栈sum; -
将队列顶端元素出栈,重复1操作,直至队列为空,此时sum中结果即为中缀表达式运算结果。
队列顶端元素对应类型值
代码
#include <iostream>
#include<string>
#include <stack>
#include <queue>
using namespace std;
stack<char> s;//存放运算符的栈
queue<string> q;//输出队列(用于计算后缀表达式)
stack<double> sum;//用于计算后缀表达式
string str = "";//读取整个数字串并保存
int isp(char c)//栈内元素优先级判断
{
switch (c)
{
case '#':
return 0;
case '(':
return 1;
case '+':
case '-':
return 3;
case '*':
case '/':
case '%':
return 5;
case ')':
return 6;
}
}
int icp(char c)//栈外元素优先级判断
{
switch (c) {
case '#':
return 0;
case ')':
return 1;
case '+':
case '-':
return 2;
case '*':
case '/':
case '%':
return 4;
case '(':
return 6;
}
}
void postfix(string input)//中缀表达式转后缀表达式代码
{
s.push('#');//将#压入栈顶
input += '#';//添加#号作为结束符
for (int i = 0; i < input.length(); i++)
{
if ((input[i] >= '0' && input[i] <= '9') || input[i] == '.')
{
str += input[i];
}
else
{
if (str.length() > 0)//将数放入直接输出到队列中
{
q.push(str);
str = "";
}
while (isp(s.top()) > icp(input[i]))
{
string a;//因为不能直接在栈和队列间转换字符和字符串类型,所以先将字符转成 字符串再出栈进队列
a = s.top();
q.push(a);
s.pop();
}
//判断站外元素优先级决定元素是应该去除(=),还是进栈(<)
if (isp(s.top()) == icp(input[i]))
{
s.pop();
}
else
{
s.push(input[i]);
}
}
}
}
int wordType(string str)//队列顶元素类型
{
if (str == "+")
{
return 1;
}
else if (str == "-")
{
return 2;
}
else if (str == "*")
{
return 3;
}
else if (str == "/")
{
return 4;
}
else {
return 0;//元素数字
}
}
void addOperation()//加运算,取运算栈的两个栈顶元素进行操作,结果压回运算栈
{
double temp1, temp2,result;
temp2 = sum.top();//先取操作数2(运算符后面的操作数)
sum.pop();
temp1 = sum.top();//再取操作数1(运算符前面的操作数)
sum.pop();
result = temp1 + temp2;
sum.push(result);
}
void subOperation()//减运算
{
double temp1, temp2, result;
temp2 = sum.top();
sum.pop();
temp1 = sum.top();
sum.pop();
result = temp1 - temp2;
sum.push(result);
}
void mulOperation()//乘运算
{
double temp1, temp2, result;
temp2 = sum.top();
sum.pop();
temp1 = sum.top();
sum.pop();
result = temp1 * temp2;
sum.push(result);
}
void divOperation()//除运算
{
double temp1, temp2, result;
temp2 = sum.top();
sum.pop();
temp1 = sum.top();
sum.pop();
result = temp1 / temp2;
sum.push(result);
}
void suffix()//计算后缀表达式,结果保留在栈sum中
{
while (q.empty() == false)
{
int objType;//队列顶元素的类型(0:数字;1:+;2:-;3:*;4:/)
objType = wordType(q.front());
switch (objType)
{
case 0:
sum.push(atof(q.front().c_str())); break;//使用c_str()方法将string转换成double型,将数字放入计算栈中
case 1:
addOperation(); break;
case 2:
subOperation(); break;
case 3:
mulOperation(); break;
case 4:
divOperation(); break;
}
q.pop(); //将队列顶元素出队列
}
}
int main()
{
string input;
string och;
cin >> input;
postfix(input);
//while (q.empty() == false)//队列不为空则输出队列元素
//{
// och = q.front();
// cout << och;
// q.pop();
//}
suffix();
cout << sum.top() << endl;
}
实验结果
结果正确,自行验证。