#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. Oracle之SQL语句的分类

    SQL简介 SQL:结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库 ...

  2. HTML背景图加载过慢解决思路

    压缩图片的大小 第一个压缩图片网站 第二个压缩图片网站

  3. selenium+python自动化105 - selenium 如何在已打开的浏览器上继续运行自动化脚本?

    前言 使用selenium 做web自动化的时候,经常会遇到这样一种需求,是否可以在已经打开的浏览器基础上继续运行自动化脚本? 这样前面的验证码登录可以手工点过去,后面页面使用脚本继续执行,这样可以解 ...

  4. urllib-访问网页的两种方式:GET与POST

    学习自:https://www.jianshu.com/p/4c3e228940c8 使用参数.关键字访问服务器 访问网络的两种方法: 1.GET 利用参数给服务器传递信息 参数data为dict类型 ...

  5. MySQL:Win10系统中设置默认编码为UTF-8

    Win10 系统下 Mysql 字符集(utf8)的设置 补充: 在[mysqld]下添加语句:init_connect='SET collation_connection = utf8_unicod ...

  6. 『现学现忘』Docker相关概念 — 4、虚拟化概念

    目录 1.虚拟化的概念 2.为什么出现虚拟化 3.虚拟化技术 1.虚拟化的概念 虚拟化是指通过虚拟化技术将计算机虚拟为多台逻辑计算机.在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操 ...

  7. Scipy和Numpy的插值对比

    技术背景 插值法在图像处理和信号处理.科学计算等领域中是非常常用的一项技术.不同的插值函数,可以根据给定的数据点构造出来一系列的分段函数.这一点有别于函数拟合,函数拟合一般是指用一个给定形式的连续函数 ...

  8. springboot----四、yaml配置注入

    四.yaml配置注入 4.1.配置文件 SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的 application.properties 语法结构 :key=value applic ...

  9. Kendo UI Grid 批量编辑使用总结

    项目中使用Kendo UI Grid控件实现批量编辑,现在将用到的功能总结一下. 批量编辑基本设置 Kendo Grid的设置方法如下: $("#grid").kendoGrid( ...

  10. tp5怎么防sql注入 xss跨站脚本攻击

    在 application/config.php 中有个配置选项 框架默认没有设置任何过滤规则,你可以是配置文件中设置全局的过滤规则 则会调用这些函数 自动过滤 // 默认全局过滤方法 用逗号分隔多个 ...