数据结构_calculator
问题描述
小 V 发明了一个神奇的整数计算器:
给定一个合法的表达式,这个计算器能求出这个表达式的最终答案。
表达式可能包含:
+:运算符,整数加法。如 1+1=2
-:运算符,整数减法。如 1-1=0
*:运算符,整数乘法。如 1*1=1
/:运算符,整数除法。如 3/2=1
(:左括号
):右括号
操作数:保证为非负整数,且操作数没有正号(如不会出现+1 等)
现在,给定一个表达式,小 V 在用这个计算器计算前想先知道最终答案是多少,你能
帮帮他吗?
★数据输入
一个合法的表达式,表达式长度不超过 1000。
★数据输出
表达式的最终结果。
★Notice
题目保证:输入的操作数,计算的中间值,计算的最终结果都在 int 范围内
★样例
1+1 2
1+2/3 1
(1+2)*3 9
解题思路
solve1
建立两个栈:数字栈、符号栈
按顺序遍历算式
遇到数字注意按多位数读取,压入数字栈
若符号栈为空或为 ' ( ' ,压入符号栈
遇到 + - / *,向前计算优先级大于等于本符号优先级的,算到 ' ( '停止。将本符号压入符号栈
优先级 / * 最高,+ - 次之
故 + - 前面的 + - * / 都要算, * / 前面的* / 要算, + -不算,遇到 + - 停止
遇到 ' ) ',向前算到 ' ( '
最后数字栈栈顶元素即为解
solve 2
将原表达式转换为后续表达式。
为能正确读取后续表达式,可在所有数字、符号间加上空格。
此时,表达式将比原表达式长,原来长度1000数组不够用,要开大一点
最后用后续表达式计算结果
附:中缀表达式转后缀表达式的方法
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
code
#include <stdio.h>
#include <iostream>
using namespace std;
#include <stack>
#include <string.h> inline bool isNum(char c)
{
return c>='' && c<='';
} inline int toInt(char c)
{
return c-'';
} int calc(int nl,int nr,char s)
{
if(s=='+') return nl+nr;
else if(s=='-') return nl-nr;
else if(s=='*') return nl*nr;
else if(s=='/') return nl/nr;
printf("errror");
return ;
} int main()
{
int i,j,k;
char str[]={};
int len;
scanf("%s",str);
len = strlen(str); stack<int> num;
stack<int> signal; for(i=;i<len;i++)
{
if(isNum(str[i]))
{
int n = toInt(str[i]);
for (j = i + ; j < len && isNum(str[j]); j++)
n = n * + toInt(str[j]);
num.push(n);
i = j - ;
}
else // is signal
{
char thissign = str[i];
if(thissign=='(' || signal.empty())
{
signal.push(thissign);
}
else if(thissign=='+' || thissign=='-')
{
while(!signal.empty() && signal.top()!='(')
{
int nr = num.top();
num.pop();
int nl = num.top();
num.pop();
num.push(calc(nl,nr,signal.top()));
signal.pop();
}
signal.push(thissign);
}
else if(thissign=='*' || thissign=='/')
{
while(!signal.empty() && ( signal.top()=='*' || signal.top()=='/') )
{
int nr = num.top();
num.pop();
int nl = num.top();
num.pop();
num.push(calc(nl,nr,signal.top()));
signal.pop();
}
signal.push(thissign);
}
else if(thissign==')')
{
while(!signal.empty() && signal.top()!='(')
{
int nr = num.top();
num.pop();
int nl = num.top();
num.pop();
num.push(calc(nl,nr,signal.top()));
signal.pop();
}
signal.pop();
}
}
}
while(!signal.empty())
{
int nr = num.top();
num.pop();
int nl = num.top();
num.pop();
num.push(calc(nl,nr,signal.top()));
signal.pop();
}
printf("%d\n",num.top());
return ;
}
数据结构_calculator的更多相关文章
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- 一起学 Java(三) 集合框架、数据结构、泛型
一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...
- 深入浅出Redis-redis底层数据结构(上)
1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...
- 算法与数据结构(十五) 归并排序(Swift 3.0版)
上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...
- 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)
本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...
- 算法与数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找
今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找 ...
- 算法与数据结构(八) AOV网的关键路径
上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...
- 算法与数据结构(七) AOV网的拓扑排序
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
- 掌握javascript中的最基础数据结构-----数组
这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...
随机推荐
- 【转】Python获取当前系统时间
转自:https://www.cnblogs.com/-ldzwzj-1991/p/5889629.html 取得时间相关的信息的话,要用到python time模块,python time模块里面有 ...
- webpack 开发环境
当项目逐渐变大,webpack 的编译时间会变长,可以通过参数让编译的输出内容带有进度和颜色. $ webpack --progress --colors 如果不想每次修改模块后都重新编译,那么可以启 ...
- java程序员图文并茂细说Unity中调用Android的接口
http://bbs.csdn.net/topics/391876421 最近做一个项目,为同事提供接口,能使他在Unity中调用Android中的函数来实现QQ登陆并获取用户信息.按照一些书上和一些 ...
- Windbg内核调试之三: 调试驱动
这次我们通过一个实际调试驱动的例子,来逐步体会Windbg在内核调试中的作用.由于条件所限,大多数情况下,很多人都是用VMware+Windbg调试内核(VMware的确是个好东西).但这样的调试需要 ...
- TCP之半关闭与CLOSE_WAIT
终止一个连接要经过4次握手.这由TCP的半关闭(half-close)造成的.既然一个TCP连接是全双工(即数据在两个方向上能同时传递,可理解为两个方向相反的独立通道),因此每个方向必须单独地进行关闭 ...
- 通过PowerShell命令给Azure VM添加CustomScriptExtension
Azure的VM提供了一种管理工具叫Azure VM Extension.它实现了一些管理虚拟机所需要的重要功能,比如:重设密码.设置RDP参数.以及许多其他关键的功能,并且Azure VM一直在添加 ...
- Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之验证码
验证码这东西,有人喜欢有人不喜欢.对于WebApi是否需要验证码,没去研究过,只是原来的SimpleCMS有,就加上吧. 在WeiApi上使用验证码,关键的地方在于WeiApi是没有状态的,也就是说, ...
- java代码I/O流类
package com.aini; //流类rr //流操作的步骤: /*1.找到指定File 2.实例化字节流.InputStream/OutputStream/Reader/Writer 3.读/ ...
- MongoTemplate聚合操作
Aggregation简单来说,就是提供数据统计.分析.分类的方法,这与mapreduce有异曲同工之处,只不过mongodb做了更多的封装与优化,让数据操作更加便捷和易用.Aggregation操作 ...
- spring bean管理
轻量级,无侵入 Bean管理 1 创建applicationContext.xml 2 配置被管理的Bean 3 获取Bean pom.xml配置 <dependency> <gro ...