#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. CentOS 7 下如何进行Python3的独立安装

    一.部署准备工作 部署环境工具检查及安装 1)安装epel-release库,以防db4-devel依赖安装失败 1 yum -y install epel-release 2)安装外部函数库(lib ...

  2. 三、ES6中数组拓展

    一.Array.of() 将参数中所有值作为元素形成数组: console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4] 参数的值可以为不同的类型: conso ...

  3. k8s-ingress部署测试以及深入理解

    1.ingress 部署有两种方式.本次采用DaemonSet部署. apiVersion: v1 kind: Namespace metadata: name: ingress-nginx --- ...

  4. pandas模块篇(终章)及初识mataplotlib

    今日内容概要 时间序列 针对表格数据的分组与聚合操作 其他函数补充(apply) 练习题(为了加深对DataFrame操作的印象) mataplotlib画图模块 今日内容详细 时间序列处理 时间序列 ...

  5. Java 替换PDF中的字体

    文档中可通过应用不同的字体来呈现不一样的视觉效果,通过字体来实现文档布局.排版等设计需要.应用字体时,可在创建文档时指定字体,也可以用新字体去替换文档中已有的字体.下面,以Java代码展示如何来替换P ...

  6. 面试官:Redis中字符串的内部实现方式是什么?

    在面试间里等候时,感觉这可真暖和呀,我那冰冷的出租屋还得盖两层被子才能睡着.正要把外套脱下来,我突然听到了门外的脚步声,随即门被打开,穿着干净满脸清秀的青年走了进来,一股男士香水的淡香扑面而来. 面试 ...

  7. php 23种设计模型 - 访问者模式

    访问者模式是一种行为型模式,访问者表示一个作用于某对象结构中各元素的操作.它可以在不修改各元素类的前提下定义作用于这些元素的新操作,即动态的增加具体访问者角色. 访问者模式利用了双重分派.先将访问者传 ...

  8. Linux常用文件管理命令详解

    cat cat命令用于连接文件并打印到标准输出设备上. 命令语法:cat [参数] [文件名] 参数说明: 参数 说明 -n 由1开始对所有输出的行数进行编号. -b 由1开始对所有输出的行数进行编号 ...

  9. Python模板引擎Jinja2使用简介

    原文链接 背景 最近在项目开发中,需要针对 Jenkins 项目进行配置,Jenkins 的 job 配置采用的是 xml,在维护配置模板的过程中就遇到了问题,因为逐步发现配置灵活性超出了字符串的范畴 ...

  10. Apache HTTPD 未知后缀解析漏洞

    环境搭建 https://blog.csdn.net/qq_36374896/article/details/84102101 该环境版本: PHP 7.x 最新版 Apache HTTPD 2.4. ...