算法与数据结构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 ...
随机推荐
- WEB中需求分析应该考虑的问题
一. 针对用户群体要考虑因素 1.用户年龄 2.选择素材 3.网站布局 4.颜色搭配 5. 用户体验及动效 6.功能便捷 用户需求.用户兴趣爱好.性格.职业.教育水平高低.消费观念.PC端和移动端哪一 ...
- hadoop生态搭建(3节点)-08.kafka配置
如果之前没有安装jdk和zookeeper,安装了的请直接跳过 # https://www.oracle.com/technetwork/java/javase/downloads/java-arch ...
- VSCode 配置 C++
每次换台电脑写c++,就要找配置,很是繁琐.这次自己写篇博客,记录下相关配置过程. 安装编译器 打开下面的网站 http://www.msys2.org ,下载 64 位的 MSYS2,按照主页上的步 ...
- python学习笔记:第19天 类的约束、异常、MD5和logging
目录 一.类的约束 二.异常处理: 三.MD5加密 四.日志(logging模块) 一.类的约束 真正写写项目的代码时都是多人协作的,所以有些地方需要约束程序的结构.也就是说,在分配任务之前就应该把功 ...
- phpcms v9 完美更换整合Ueditor 1.3
phpcms这套系统相信大家不陌生,它做的很不错,但是也有好多地方不满足我们的需求,比如在线编辑器. 它自带的是CKEditor编辑器,功能较少,比如代码加亮功能就没有. 所以我来说一下怎么替换php ...
- C语言跳水比赛预测结果
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果A选手说:B第二,我第三:B选手说:我第二,E第四:C选手说:我第一,D第二:D选手说:C最后,我第三:E选手说:我第四,A第一:比赛结束后,每 ...
- 小程序开发-11-Promise正确用法与函数签名设计技巧
配置taBar "tabBar": { "selectedColor": "#000000", "backgroundColor& ...
- 第五节 Go数据结构之队列
一.什么是队列 数据结构里的队列就是模仿现实中的排队.如上图中狗狗排队上厕所,新来的狗狗排到队伍最后,最前面的狗狗撒完尿走开,后面的跟上.可以看出队列有两个特点: (1) 新来的都排在队尾: (2) ...
- 【Hutool】Hutool工具类之随机工具——RandomUtil
commons-lang中对应也有RanddomUtils.RandomStringUtils 直接从类结构开始入手: 基本都是见名知意了,就不一一展开:点开源码可以看到算是比较通俗易懂的对Rando ...
- Solr第二讲——SolrJ客户端的使用与案例
一.Solrj的使用 1.什么是Solrj solrj是访问Solr服务的java客户端(就像通过jedis操作redis一样),提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过Sol ...