#include <iostream>

using std::cin;
using std::cout;
using std::endl; template<typename T>
class Stack
{
public:
Stack(int _size = 20) :size(_size), mtop(0)
{
data = new T[size]();
}
~Stack()
{
delete[] data;
}
/* 判空 */
bool empty()
{
return mtop == 0;
}
void push(int val)
{
if (Full())
{
throw std::exception("error: Stack is Full !");
}
data[mtop] = val;
mtop++;
}
T top()
{
if (empty())
{
throw std::exception("error: The stack is empty !");
}
return data[mtop - 1];
}
void pop()
{
if (empty())
{
throw std::exception("error: Stack is Empty !");
}
mtop--;
}
void show()
{
if (empty())
{
cout << endl;
}
else
{
int i = 0;
while (i < mtop)
{
cout << data[i] << " ";
i++;
}
cout << endl;
}
}
private:
bool Full()
{
return mtop == size;
}
T* data;
int mtop;
int size;
}; /* 计算器类 */
class Calculator
{
public:
Calculator(int _size = 20):size(_size),result(0)
{
str = new char[_size + 1]();
}
~Calculator()
{
delete[] str;
}
/* 输入 */
void setData()
{
cin.getline(str, size - 1); //最多输入size -1个,末尾加'/0'
}
/* 中缀转后缀 */
void InfixToSuffix(); /* 把str输入的中缀式转换为后缀式 */
/* 后缀计算 */
void Compure();
/* 计算结果 */
double GetResult()
{
return result;
}
private:
bool IsPop(char a, char b);
char* str;
double result;
int size; }; int main()
{
while (1) {
Calculator ca;
ca.setData();
ca.InfixToSuffix();
ca.Compure();
cout << ca.GetResult() << endl; }
return 0;
} bool Calculator::IsPop(char a, char b) //a为待比较符号,b为符号栈栈顶元素
{
if (b == '(') return false;
if (a == '*' || a == '/')
{
if (b == '+' || b == '-')
{
//可以如符号栈
return false;
}
else
{
return true;
}
}
//if (a == '+' || a == '-')
//{
//a符号为最低优先级,符号栈出栈
return true;
//}
} /* 中缀转后缀 入栈 */
void Calculator::InfixToSuffix()
{
char* des = new char[size]();
/* 符号栈 */
Stack<char> symbol; int i = 0;
int k = 0;
while (str[i] != '\0')
{
/*----------- 特殊符号判断------------------------------*/
if (str[i] == ' ') //如果当前字符是空格,则往后走一个
{
i++;
continue;
}
else if (str[i] == '(') //左括号直接入栈
{
symbol.push(str[i]);
}
else if (str[i] == ')') //遇到 ) ,输出( )之间的所有符号
{
while (symbol.top() != '(')
{
des[k++] = symbol.top();
des[k++] = ' ';
symbol.pop();
}
symbol.pop();
}
/*----------------- 数字 -------------------------------*/
else if (isdigit(str[i]))
{
des[k++] = str[i];
if (!isdigit(str[i + 1])) //数字后加空格
{
des[k++] = ' ';
}
}
/*----------------- 运算符 -------------------------------*/
else
{
switch (str[i])
{
case '+':case '-':case '*':case '/':
if (symbol.empty()) //如果符号栈为空,直接入符号
{
symbol.push(str[i]);
}
else //否则,判断是否选择入符号栈还是出栈顶元素
{
if (IsPop(str[i], symbol.top())) //出符号栈
{
des[k++] = symbol.top();
symbol.pop();
continue;
}
else //当前符号优先级高,入符号栈
{
symbol.push(str[i]);
}
}
break;
default:
break;
} } i++; /* 遍历下一字符 */
}
/*字符串已遍历完,把符号栈中剩余的符号入栈到数字栈中 */
while (!symbol.empty())
{
des[k++] = symbol.top();
symbol.pop();
}
des[k] = '\0'; char* tmp = des;
des = str;
str = tmp;
delete[]des;
} void Calculator::Compure()
{
/* 辅助栈 */
Stack<double> st; int i = 0;
while (str[i] != '\0')
{
/*----------- 特殊符号判断------------------------------*/
if (str[i] == ' ') //如果当前字符是空格,则往后走一个
{
i++;
continue;
} /*----------------- 数字 -------------------------------*/
else if (isdigit(str[i]))
{
double tmp = 0;
while (str[i] != ' ')
{
tmp = tmp * 10 + str[i] - '0';
i++;
}
st.push(tmp);
}
/*----------------- 运算符 -------------------------------*/
else if (!st.empty()) //非空
{
double tmp = 0;
switch (str[i])
{
case '+':
tmp += st.top();
st.pop();
tmp += st.top();
st.pop();
st.push(tmp);
break;
case '-':
tmp -= st.top();
st.pop();
tmp += st.top();
st.pop();
st.push(tmp);
break;
case '*':
tmp = st.top();
st.pop();
tmp *= st.top();
st.pop();
st.push(tmp);
break;
case '/':
{
tmp = st.top();
st.pop();
if (tmp != 0)
{
tmp = st.top() / tmp;
st.pop();
st.push(tmp);
}
else
{
throw std::exception("error: Divisor of 0 !");
}
}
break;
default:
break;
} } i++; /* 遍历下一字符 */
} this->result = st.top();
st.top();
}

运行截图:

C++ | 栈的应用(逆波兰算法) | 计算器的更多相关文章

  1. HDU1237 简单计算器 【栈】+【逆波兰式】

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  2. 6, java数据结构和算法: 栈的应用, 逆波兰计算器, 中缀表达式--> 后缀表达式

    直接上代码: public class PolandCalculator { //栈的应用:波兰计算器: 即: 输入一个字符串,来计算结果, 比如 1+((2+3)×4)-5 结果为16 public ...

  3. K:逆波兰算法

    相关介绍:  一种求解字符串形式的表达式的结果的算法,该算法在求解时,需要先将我们平日里习惯上使用的中序表达式的模式转化为等价的后序(后缀)表达式的模式,之后再通过求解出该后序(后缀)表达式的结果而得 ...

  4. 第四章 栈与队列(c5)栈应用:逆波兰表达式

  5. c# 逆波兰式实现计算器

    语文不好,不太会组织语言,希望不要太在意. 如题,先简要介绍一下什么是逆波兰式  通常我们在写数学公式的时候  就是a+b+c这样,这种表达式称为中缀表达式,逆波兰式又称为后缀表达式,例如a+b 后缀 ...

  6. 逆波兰表达式的C实现

    复习下数据结构,用栈简单实现逆波兰表达式,参考文档: http://www.nowamagic.net/librarys/veda/detail/2307 http://www.nowamagic.n ...

  7. C#数据结构与算法系列(十):逆波兰计算器——逆波兰表达式(后缀表达式)

    1.介绍 后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后 2.举例说明 (3+4)*5-6对应的后缀表达式就是3 4 +5 * 6 - 3.示例 输入一个逆波兰表达式(后缀表达 ...

  8. HDU1237 简单的计算器 【堆】+【逆波兰式】

    简单的计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  9. shunting-yard 调度场算法、中缀表达式转逆波兰表达式

    中缀表达式 1*(2+3) 这就是一个中缀表达式,运算符在数字之间,计算机处理前缀表达式和后缀表达式比较容易,但处理中缀表达式却不太容易,因此,我们需要使用shunting-yard Algorith ...

随机推荐

  1. linux时钟校准

    ## 查看系统时间 date ## 查看硬件时间 hwclock ## 手动设置时间 date -s "20210507 17:55:00" ## 同步硬件时间 hwclock - ...

  2. 痞子衡嵌入式:揭秘i.MXRTxxx系列上串行NOR Flash双程序可交替启动设计

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT500/600上串行NOR Flash双程序可交替启动设计. 在上一篇文章 <i.MXRT1170上串行NOR Fla ...

  3. MySQL 学习-进阶

    MySQL高级学习 一.MySQL 事务 1.1.事务的概念 一条或多条 SQL 语句组成一个执行单元,其特点是这个单元要么同时成功要么同时失败,单元中的每条 SQL 语句都相互依赖,形成一个整体,如 ...

  4. lvs-安装以及脚本

    1.dr 采用修改mac 地址方式,使用二层网络mac路由.所以rs调度的vip 和 后端的realip必须是同一网段. 注意事项:真是服务器上本地lo网卡需要配置为和rs调度的vip 一样. 这样真 ...

  5. Windows Service 安装、启动和卸载

    win+R输入cmd,以管理员身份运行cmd: 安装: 1.cd C:\Windows\Microsoft.NET\Framework\v4.0.30319   回车 2.输入(InstallUtil ...

  6. java中的异常(Exception)

    基本概念 将程序执行中发生的不正常的情况称为"异常".开发中的语法错误和逻辑错误不是异常 执行过程中的异常事件可分为两大类 错误(Error):Java虚拟机无法解决的严重问题.例 ...

  7. PHP 的网站主要攻击方式有哪些?

    1.命令注入(Command Injection)2.eval 注入(Eval Injection)3.客户端脚本攻击(Script Insertion)4.跨网站脚本攻击(Cross Site Sc ...

  8. 如何使用 Hexo 搭建个人博客

    原文链接 什么是 Hexo ? Hexo 是一个简单快速的静态博客框架,可以通过编辑 Markdown 文档生成好看的静态博客. 搭建 Hexo 要求 安装 Hexo 十分简单,只需要 Node.js ...

  9. 软件工程homework-004

    软件工程软件工程homework-004 博客信息 沈阳航空航天大学计算机学院2020软件工程作业 作业要求 https://edu.cnblogs.com/campus/sau/Computer17 ...

  10. TypeScript-axios模块进行封装的操作与一些想法

    所谓封装与模块化,对我这种初学者来说,个人理解就是解耦,比如说,当我们前端一个项目使用了现在流行的模块,但是没有对其进行封装处理,包括一些相同的代码逻辑,把他们分散在各个组件当中,这样一来整个项目对于 ...