★实验任务

小 V 发明了一个神奇的整数计算器:

给定一个合法的表达式,这个计算器能求出这个表达式的最终答案。

表达式可能包含:

+:运算符,整数加法。如 1+1=2

-:运算符,整数减法。如 1-1=0

:运算符,整数乘法。如 11=1

/:运算符,整数除法。如 3/2=1

(:左括号

):右括号

操作数:保证为非负整数,且操作数没有正号(如不会出现+1 等)

现在,给定一个表达式,小 V
在用这个计算器计算前想先知道最终答案是多少,你能 帮帮他吗?

★数据输入

一个合法的表达式,表达式长度不超过 1000。

★数据输出

表达式的最终结果。

★Notice

题目保证:输入的操作数,计算的中间值,计算的最终结果都在 int 范围内

★样例

输入示例 输出示例
1+1
1+2/3
(1+2)*3
2
1
9

★思路

  solve1

    建立两个栈:数字栈、符号栈

    按顺序遍历算式

    遇到数字注意按多位数读取,压入数字栈

    若符号栈为空或为 ' ( ' ,压入符号栈

    遇到 + - / ,向前计算优先级大于等于本符号优先级的,算到 ' ( '停止。将本符号压入符号栈

    优先级 / * 最高,+ - 次之

    故 + - 前面的 + - * / 都要算, * / 前面的
/ 要算, + -不算,遇到 + - 停止

    遇到 ' ) ',向前算到 ' ( '

    最后数字栈栈顶元素即为解

  solve 2

    将原表达式转换为后续表达式。

    为能正确读取后续表达式,可在所有数字、符号间加上空格。

    此时,表达式将比原表达式长,原来长度1000数组不够用,要开大一点

    最后用后续表达式计算结果

  附:中缀表达式转后缀表达式的方法

    1.遇到操作数:直接输出(添加到后缀表达式中)

    2.栈为空时,遇到运算符,直接入栈

    3.遇到左括号:将其入栈

    4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。

    5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈

    6.最终将栈中的元素依次出栈,输出。

★Code


#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstring>
using namespace std; char priority(char pre, char post)
{
if (pre == '+')
{
if (post == '+') return '>';
else if (post == '-') return '>';
else if (post == '*') return '<';
else if (post == '/') return '<';
else if (post == '(') return '<';
else if (post == ')') return '>';
}
else if (pre == '-')
{
if (post == '-') return '>';
else if (post == '+') return '>';
else if (post == '*') return '<';
else if (post == '/') return '<';
else if (post == '(') return '<';
else if (post == ')') return '>';
}
else if (pre == '*')
{
if (post == '*') return '>';
else if (post == '/') return '>';
else if (post == '+') return '>';
else if (post == '-') return '>';
else if (post == '(') return '<';
else if (post == ')') return '>';
}
else if (pre == '/')
{
if (post == '/') return '>';
else if (post == '*') return '>';
else if (post == '+') return '>';
else if (post == '-') return '>';
else if (post == '(') return '<';
else if (post == ')') return '>';
}
else if (pre == '(')
{
if (post == '*') return '<';
else if (post == '/') return '<';
else if (post == '+') return '<';
else if (post == '-') return '<';
else if (post == '(') return '<';
else if (post == ')') return '=';
}
}
int caculate(int Operand1, int Operand2, char Operator) ;
int calculateResult(string str) { //用于计算计算生成算式的值
vector< int > Operands; //运算数栈
vector< char > Operators; //运算符栈
int OperandTemp = 0;
char LastOperator = 0; //记录上一次所遇到的符号
for (int i = 0; i < str.size(); i++) { //此循环用于去括号
char ch = str[i];
if ('0' <= ch && ch <= '9') {
OperandTemp = OperandTemp * 10 + ch - '0';
}
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')') {
if (ch != '(' && LastOperator != ')') { //结合本次和上次所遇见的符号来判断是否需要将当前存储的运算数压入栈
Operands.push_back(OperandTemp);
OperandTemp = 0;
}
char Opt2 = ch;
for (; Operators.size() > 0;) {
char Opt1 = Operators.back();
char CompareRet = priority(Opt1,Opt2); //用当前符号与栈顶符号来对算式简化
if (CompareRet == '>') { //当前的符号的优先级小于栈顶符号时就可以将栈顶符号计算掉并将结果压入栈
int Operand2 = Operands.back();
Operands.pop_back();
int Operand1 = Operands.back();
Operands.pop_back();
Operators.pop_back();
int Ret = caculate(Operand1, Operand2, Opt1);
Operands.push_back(Ret);
}
else if (CompareRet == '<') { //当前的符号优先级大于栈顶符号不能进行运算所以跳出循环来存储当前符号
break;
}
else if (CompareRet == '=') { //这个是“(”,“) ”结合的情况 所以移除“(”并退出循环
Operators.pop_back();
break;
}
}
if (Opt2 != ')') {
Operators.push_back(Opt2);
}
LastOperator = Opt2;
}
}
if (LastOperator != ')') { //接下来就是计算一个不含括号的算式了
Operands.push_back(OperandTemp);
}
for (; Operators.size() > 0;) {
int Operand2 = Operands.back();
Operands.pop_back();
int Operand1 = Operands.back();
Operands.pop_back();
char Opt = Operators.back();
Operators.pop_back();
int Ret = caculate(Operand1, Operand2, Opt);
Operands.push_back(Ret);
}
return Operands.back(); //返回结果
}
int caculate(int Operand1, int Operand2, char Operator) { //计算函数
int result = 0;
if (Operator == '+') {
result = Operand1 + Operand2;
}
if (Operator == '-') {
result = Operand1 - Operand2;
}
if (Operator == '*') {
result = Operand1*Operand2;
}
if (Operator == '/') {
result = Operand1 / Operand2;
}
return result;
}
int main()
{
string str;
cin>>str;
int ans=calculateResult(str);
cout<<ans;
return 0;
}

算法与数据结构3.3 calculator的更多相关文章

  1. 算法与数据结构基础 - 贪心(Greedy)

    贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...

  2. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  3. python 下的数据结构与算法---2:大O符号与常用算法和数据结构的复杂度速查表

    目录: 一:大O记法 二:各函数高阶比较 三:常用算法和数据结构的复杂度速查表 四:常见的logn是怎么来的 一:大O记法 算法复杂度记法有很多种,其中最常用的就是Big O notation(大O记 ...

  4. LeetCode_算法及数据结构覆盖统计

    [输入]共计151道题的算法&数据结构基础数据 (见附录A) [输出-算法]其中有算法记录的共计 97道 ,统计后 结果如下  top3(递归,动态规划,回溯) 递归 动态规划 回溯 BFS ...

  5. JavaScript算法与数据结构知识点记录

    JavaScript算法与数据结构知识点记录 zhanweifu

  6. Linux内核中的算法和数据结构

    算法和数据结构纷繁复杂,但是对于Linux Kernel开发人员来说重点了解Linux内核中使用到的算法和数据结构很有必要. 在一个国外问答平台stackexchange.com的Theoretica ...

  7. Python算法与数据结构--求所有子数组的和的最大值

    Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个 ...

  8. 【算法与数据结构专场】BitMap算法基本操作代码实现

    上篇我们讲了BitMap是如何对数据进行存储的,没看过的可以看一下[算法与数据结构专场]BitMap算法介绍 这篇我们来讲一下BitMap这个数据结构的代码实现. 回顾下数据的存储原理 一个二进制位对 ...

  9. 算法与数据结构(一) 线性表的顺序存储与链式存储(Swift版)

    温故而知新,在接下来的几篇博客中,将会系统的对数据结构的相关内容进行回顾并总结.数据结构乃编程的基础呢,还是要不时拿出来翻一翻回顾一下.当然数据结构相关博客中我们以Swift语言来实现.因为Swift ...

随机推荐

  1. Nginx(haproxy)+keepalived+Tomcat双主高可用负载均衡

    周末的时候一个正在学Linux的朋友问我,高可用怎么玩?我和他微信了将近三个小时,把Nginx和haproxy双主高可用教给他了,今天突然想把这个给写进博客里,供给那些正在学习Linux系统的朋友们, ...

  2. CentOS7 LNMP+phpmyadmin环境搭建(三、安装phpmyadmin)

    之前我们已经安装了lnmp的环境,现在让我们来安装phpmyadmin. 跟前一样,yum默认的库里是没有phpmyadmin的,我们需要从epel库里进行安装,之前已经安装过epel的朋友就可以直接 ...

  3. CI框架视图继承

    CI(CodeIgniter)框架 视图继承 这个代码不是我撸的 ... 当时在哪儿找的忘了 ... 如果有侵权什么的 ... 联系我删了 ... 需要去core里面创建一个MY_loader.php ...

  4. day 20 约束 异常处理 MD5

    1.类的约束(重点): 写一个父类.  父类中的某个方法要抛出一个异常  NotImplementError # 项目经理 class Base:     # 对子类进行了约束. 必须重写该方法    ...

  5. python学习笔记:第14天 内置函数补充和递归

    一.匿名函数 匿名函数主要是为了解决一些简单需求而设计的一种函数,匿名函数的语法为: lambda 形参: 返回值 先来看一个例子: # 计算n的n次方 In[2]: lst = lambda n: ...

  6. 用Python生成词云

    词云以词语为基本单元,根据词语在文本中出现的频率设计不同大小的形状以形成视觉上的不同效果,从而使读者只要“一瞥“即可领略文本的主旨.以下是一个词云的简单示例: import jieba from wo ...

  7. Python学习笔记五:字符串常用操作,字典,三级菜单实例

    字符串常用操作 7月19日,7月20日 ,7月22日,7月29日,8月29日,2月29日 首字母大写:a_str.capitalize() 统计字符串个数:a_str.count(“x”) 输出字符, ...

  8. UART学习之路(四)VerilogHDL实现的简单UART,VIVADO下完成仿真

    用VerilogHDL实现UART并完成仿真就算是对UART整个技术有了全面的理解,同时也算是Verilog入门了.整个UART分为3部分完成,发送模块(Transmitter),接收模块(Recei ...

  9. MP3 编码解码 附完整c代码

    近期一直不间断学习音频处理,一直也没想着要去碰音频编解码相关. 主要是觉得没什么实际的作用和意义. 不管视频编解码,图像编解码,音频编解码,都有很多组织基金在推动. 当然,在一些特定的情景下,需要用起 ...

  10. window下创建虚拟环境

    一. windows下创建虚拟环境 1. 终端下执行命令:python -m pip install -upgrade pip 2. pip install virtualenv 3. 在本地创建一个 ...