算法与数据结构3.3 calculator
★实验任务
小 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的更多相关文章
- 算法与数据结构基础 - 贪心(Greedy)
贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...
- 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树
http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...
- python 下的数据结构与算法---2:大O符号与常用算法和数据结构的复杂度速查表
目录: 一:大O记法 二:各函数高阶比较 三:常用算法和数据结构的复杂度速查表 四:常见的logn是怎么来的 一:大O记法 算法复杂度记法有很多种,其中最常用的就是Big O notation(大O记 ...
- LeetCode_算法及数据结构覆盖统计
[输入]共计151道题的算法&数据结构基础数据 (见附录A) [输出-算法]其中有算法记录的共计 97道 ,统计后 结果如下 top3(递归,动态规划,回溯) 递归 动态规划 回溯 BFS ...
- JavaScript算法与数据结构知识点记录
JavaScript算法与数据结构知识点记录 zhanweifu
- Linux内核中的算法和数据结构
算法和数据结构纷繁复杂,但是对于Linux Kernel开发人员来说重点了解Linux内核中使用到的算法和数据结构很有必要. 在一个国外问答平台stackexchange.com的Theoretica ...
- Python算法与数据结构--求所有子数组的和的最大值
Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个 ...
- 【算法与数据结构专场】BitMap算法基本操作代码实现
上篇我们讲了BitMap是如何对数据进行存储的,没看过的可以看一下[算法与数据结构专场]BitMap算法介绍 这篇我们来讲一下BitMap这个数据结构的代码实现. 回顾下数据的存储原理 一个二进制位对 ...
- 算法与数据结构(一) 线性表的顺序存储与链式存储(Swift版)
温故而知新,在接下来的几篇博客中,将会系统的对数据结构的相关内容进行回顾并总结.数据结构乃编程的基础呢,还是要不时拿出来翻一翻回顾一下.当然数据结构相关博客中我们以Swift语言来实现.因为Swift ...
随机推荐
- PHP二维码生成
原文链接:http://www.qqdeveloper.com/detail/14/1.html 代码下载地址:链接:http://pan.baidu.com/s/1dFgqiaP 密码:lex5 材 ...
- linux 查看内置命令
使用: man shell builtins 查找结果如下:
- Java设计模式(6)——创建型模式之原型模式(Prototype)
一.概述 概念 // 引用自<Java与模式> UML图 第二种:登记式 二.实践 先导知识 对象的拷贝: 直接赋值:此时只是相当于a1,a2指向同一个对象,无论哪一个操作的都是同一个对象 ...
- windows 设置tomcat为自动启动服务
1.下载免安装tomcat包,解压 2.配置环境变量: 点击新建,创建一个 变量名为:CATALINA_HOME 变量值为:tomcat解压文件的位置, 例如 F:\apache-tomcat ...
- 理解C指针: 一个内存地址对应着一个值
一个内存地址存着一个对应的值,这是比较容易理解的. 如果程序员必须清楚地知道某块内存存着什么内容和某个内容存在哪个内存地址里了,那他们的负担可想而知. 汇编语法对“一个内存地址存着一个对应的数” ...
- 【POJ2182】Lost Cows
[POJ2182]Lost Cows 题面 vjudge 题解 从后往前做 每扫到一个点\(i\)以及比前面小的有\(a[i]\)个数 就是查询当前的第\(a[i]+1\)小 然后查询完将这个数删掉 ...
- 阅读笔记《JavaScript语言精粹》
阅读笔记<JavaScript语言精粹> 对象 1.检索属性 使用[]和. 2.引用传递 JavaScript的简单数据类型包括数字.字符串.布尔值.null值和undefined值.其它 ...
- SpringCloud Eureka 服务注册与服务发现
一.Eureka简介 spring Cloud Netflix技术栈中,Eureka作为服务注册中心对整个微服务架构起着最核心的整合作用.有了服务发现与注册,你就不需要整天改服务调用的配置文件了,你只 ...
- 「专题训练」Air Raid(HDU-1151)
题目 在一个城市里有\(n\)个地点和\(k\)条道路,道路是无环的(也就是说一定可以二分染色--回路长度为偶数0),现在伞兵需要去n个地点视察,只能沿着路的方向走,问最少需要多少伞兵. 分析 这是什 ...
- uvaoj 1081510815 - Andy's First Dictionary(set应用)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=835&page= ...