C++后缀表达式计算

C++后缀表达式计算

继续上篇文章,实现计算器简单计算的功能

上篇文章C++中缀表达式转后缀表达式已经将中缀表达式转换成后缀表达式并保存在队列q中

后缀表达式算法思想:

  1. 读取队列q顶端元素,并判断元素类型
    (1)若是数,将数压入运算栈sum中;
    (2)若是运算符,取出栈sum顶端的两个元素计算,结果压回栈sum;

  2. 将队列顶端元素出栈,重复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;
}

实验结果

在这里插入图片描述
结果正确,自行验证。

  • 3
    点赞
  • 0
    评论
  • 12
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

智商负250

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值