数据结构_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 ...
随机推荐
- OpenCV-Python在图片上输出中文
OpenCV中在图片上输出中文一般需要借助FreeType库实现.FreeType库是一个完全免费(开源)的.高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件.但使用FreeType ...
- HAWQ 操作笔记
1.HAWQ 是不支持主键和外建的,官方文档明确给出 Notes Using OIDs in new applications is not recommended. Avoid assuming t ...
- 学习动态性能表(16)--v$rowcache
学习动态性能表 第16篇--V$ROWCACHE 2007.6.12 本视图显示数据字典缓存(也叫rowcache)的各项统计.每一条记录包含不同类型的数据字典缓存数据统计,注意数据字典缓存有层次差 ...
- Sqoop-从hive导出分区表到MySQL
经多次验证,发现并没有特殊的方法能够直接把多个分区一次性读入,并插入MySQL的方法,以后发现会在此添加. Sqoop只提供了从MySQL导入到HIVE分区表的相关参数,反向并无特别参数. 从HIVE ...
- Python collections系列之双向队列
双向队列(deque) 一个线程安全的双向队列 1.创建一个双向队列 import collections d = collections.deque() d.append(') d.appendle ...
- 蓝桥杯 算法训练 ALGO-141 P1102
算法训练 P1102 时间限制:1.0s 内存限制:256.0MB 定义一个学生结构体类型student,包括4个字段,姓名.性别.年龄和成绩.然后在主函数中定义一个结构体数组(长度不超过10 ...
- vijos1906:联合权值
描述 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 WiWi, 每条边的长度均为 1.图上两点(u, v)的距离定义为 u 点到 v 点的最短距离. ...
- ramfs, rootfs and initramfs
ramfs, rootfs and initramfs October 17, 2005 Rob Landley <rob@landley.net> =================== ...
- (转)SC命令---安装、开启、配置、关闭windows服务 bat批处理
本文转载自:http://blog.csdn.net/moruna/article/details/9190733 废话不多说,看命令行更直接! 一.直接使用cmd来进行服务的一些操作 1.安装服务 ...
- java代码继承难点。构造方法的调用
总结:子类默认调用父类的无参构造方法.重写时,父类方法将被覆盖,不被调用,在子类中可以使用super.方法():可以实现 运行显示: evente.x:55 evente.x:55 B.y:57 pa ...