算法与数据结构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 ...
随机推荐
- md5的理解
md5之所以很难破解,是因为它是不可逆的(下面会解释),它是一种散列函数(哈希函数),并且是单向密码体制,即:从明文到密文的不可逆映射,只有加密过程没有解密过程. 为何说是不可逆映射呢?这是因为,md ...
- Vuex的第一次接触
前言:最近在做Vue实现去哪网,想要实现在城市列表页面,点击某个城市的时候,主页的头部的城市会随着改变,就是首页和城市页面有共用的数据要分享,这里使用Vuex 1. Vuex是什么? 是Vue官方推荐 ...
- HTML+jq简单轮播图
.main{ width: 100%; min-width: 1100px; display: table; margin: 0 auto; text-align: ce ...
- JQuery制作网页——第九章 表单验证
1. 表单验证:减轻服务器的压力.保证输入的数据符合要求: 2. 常用的表单验证:日期格式.表单元素是否为空.用户名和密码.E-mail地址.身份证号码等: 3. 表单验证的思路: 1. ...
- springboot的junit4模拟request、response对象
关键字: MockHttpRequest.Mock测试 问题: 在模拟junit的request.response对象时,会报如下空指针异常. 处理方法: 可用MockHttpServletReque ...
- TinyMCE插件:Filemanager [4.x-6.x] 文件名统一格式化
上传图片程序(filemanager/upload.php) 在if (!empty($_FILES) && $upload_files)中上传图片时,在文件正式上传至服务器前,有一次 ...
- phpstudy lamp
phpStudy for Linux (lnmp+lamp一键安装包 现在不考虑安装这个 (完整版:http://lamp.phpstudy.net/phpstudy-all.bin) 安装: wg ...
- Email Helper
using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk.Que ...
- JAVA基础 - 自定义异常类
自定义异常类,代码还不是很明白,先存着以后参考. package week6; class ScoreException extends Exception { private static fina ...
- Lingo解决最优化问题
目录 Lingo解决优化问题 前言 一.优化模型介绍 二.运输问题 2.1 问题描述 2.2 问题分析 2.2 优化模型构建 2.3 模型求解 2.4 求解结果 三.待更新 Lingo解决优化问题 @ ...