CFGym 100198G 题解
一、题目链接
http://codeforces.com/gym/100198/problem/G
二、题意
看样例就能明白,写表达式解析器。
三 、思路
一看这题目,立马就会想到“后缀表达式”,考虑到这里有变量,在把中缀表达式变为后缀表达式时,把变量替换成常量即可。注意,define 2 3 表示,下面的2用3来替换。和C语言是一样的。
PS:然而,我用Java写的,总是RE在第四个样例,实在找不到哪里抛异常了。各位同行,如果您能找到我的代码的bug,烦请您在评论区留下出bug的样例。谢谢!
四、源代码
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.Stack; public class Main { static final String digitPattern = "-?\\d+"; static final File fin = new File("plcool.in"); static final File fout = new File("plcool.out"); static String input; static ArrayList<String> inExp = new ArrayList<String>(); static ArrayList<String> postExp = new ArrayList<String>(); static Map<Character, Integer> prior = new HashMap<Character, Integer>(); static Map<String, String> define = new HashMap<String, String>(); static InputStream is = null; static PrintStream ps = null; static { prior.put('^', 3); prior.put('*', 2); prior.put('/', 2); prior.put('%', 2); prior.put('+', 1); prior.put('-', 1); prior.put('(', 0); prior.put(')', 0); } static String findRoot(String key) { if(!define.containsKey(key))return key; else return findRoot(define.get(key)); } static int power(int x, int y) { int res = 1; while(y > 0) { if((y & 1) == 1)res *= x; x = x * x; y >>= 1; } return res; } static int mod(int x, int y) { int sign = ((x >>> 31) ^ (y >>> 31)) == 0 ? 1 : -1; return (Math.abs(x) % Math.abs(y)) * sign; } static void split() { inExp.clear(); int s = 0, t = 0, len = input.length(); boolean befOper = false; for (int i = 0; i < len; ++i) { if(Character.isDigit(input.charAt(i)) || (input.charAt(i) == '-' && (befOper || i == 0))) { for(s = i++;i < len && Character.isDigit(input.charAt(i)); ++i); inExp.add(input.substring(s, i)); --i; befOper = false; } else if(Character.isLetter(input.charAt(i))) { for(s = i;i < len && (Character.isLetter(input.charAt(i)) || Character.isDigit(input.charAt(i))); ++i); inExp.add(input.substring(s, i)); --i; } else if(prior.containsKey(input.charAt(i))) { inExp.add(input.charAt(i) + ""); befOper = true; } } //inExp.forEach(e -> ps.print(e + " ")); for (int i = 0, sz = inExp.size(); i < sz; ++i) { String now = inExp.get(i); if (define.containsKey(now)) { String root = findRoot(now); if(!root.matches(digitPattern))root = "0"; inExp.set(i, root); } else if(!prior.containsKey(now.charAt(0)) && !now.matches(digitPattern))inExp.set(i, "0"); } //inExp.forEach(e -> ps.print(e + " ")); } static Stack<Character> opers = new Stack<Character>(); static void toPost() { opers.clear(); postExp.clear(); for (String s : inExp) { if (s.matches(digitPattern)) postExp.add(s); else { if (opers.isEmpty()) opers.push(s.charAt(0)); else { char top = opers.peek(); char c = s.charAt(0); if (s.equals(")")){ while (!opers.isEmpty() && opers.peek() != '(') { postExp.add(opers.pop() + ""); } if (!opers.isEmpty() && opers.peek() == '(') opers.pop(); } else if((c != '(' && c != '^' && prior.get(c) <= prior.get(top))){ for(top = opers.peek();prior.get(c) <= prior.get(top);) { postExp.add(opers.pop() + ""); if(!opers.isEmpty())top = opers.peek(); else break; } opers.push(c); } else opers.push(c); } } } while(!opers.isEmpty()) { char c = opers.pop(); if(c == ')')continue; else postExp.add(c + ""); } //postExp.forEach(e -> ps.print(e + " ")); } static Stack<Integer> digits = new Stack<Integer>(); static int calcResult() { digits.clear(); for(String s : postExp) { if(s.matches(digitPattern))digits.push(Integer.parseInt(s)); else { char c = s.charAt(0); int last1 = digits.pop(), last2 = digits.pop(); switch (c) { case '-':{ digits.push(last2 - last1); break; } case '+':{ digits.push(last2 + last1); break; } case '*':{ digits.push(last2 * last1); break; } case '/':{ digits.push(last2 / last1); break; } case '%':{ digits.push(mod(last2, last1)); break; } case '^':{ digits.push(power(last2, last1)); break; } } } } return digits.pop(); } static String[] parts; public static void main(String[] args) throws Exception { // is = new FileInputStream(fin); // ps = new PrintStream(new FileOutputStream(fout)); is = System.in; ps = System.out; Scanner scanner = new Scanner(is); while (scanner.hasNextLine()) { input = scanner.nextLine().trim().toLowerCase(); if (input.charAt(0) == 'p') { input = input.replaceAll(" ", ""); input = input.substring(5); split(); toPost(); int res = calcResult(); ps.println(res); } else { parts = input.split(" "); if (define.containsKey(parts[1])) continue; else { String root1 = findRoot(parts[1]); String root2 = findRoot(parts[2]); if(!root1.equals(root2))define.put(parts[1], parts[2]); } } } scanner.close(); } }
CFGym 100198G 题解的更多相关文章
- CFGym 101490J 题解
一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你n个点,代表学生所在位置,n个点,代表老师所在位置.每个学生分配一个老师.让你找出一个最小的学生 ...
- CFGym 101490E 题解
一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你一个图,n个点,m条边,一个x,从顶点1走到顶点n.假设从顶点1走到顶点n的最短路为d,x代表你 ...
- CFGym 101161I 题解
一.题目链接 http://codeforces.com/gym/101161/problem/I 二.题意 给定一棵树,一个初始的省会城市,若干个询问,0表示修改省会城市,1表示查询去省会必须经过指 ...
- CFGym 101194L 题解
一.题目链接 http://codeforces.com/gym/101194/problem/L 二.题意 有4个队伍,要打6场比赛(刚好每两个队伍都能相互比一次),若A和B比赛有3种结果: A赢B ...
- CFGym 101194D 题解
一.题目链接 http://codeforces.com/gym/101194/problem/D 二.题意 给定一个数字n和一个数字k,一个n个整数的序列,让你在里面找尽可能多的长度为k的符合“要求 ...
- CFGym 101505I 题解
一.题目链接 http://codeforces.com/gym/101505 二.题意 这题其实主要就是题意,理解题意后,就是水题了.我想了下,主要原因就是这几点: 1.题意太过英文化,很多句子不能 ...
- CFGym 100211J 题解
一.题目 二.题意 给定一个字母表(最多也就是英文小写字母的前10个字母),一个交换表,两个字符串,判断字符串A能否通过交换表的交换方式变成字符串B. 三.思路 1.一开始,比赛时,我半模拟半记忆化地 ...
- [CF-GYM]Abu Tahun Mod problem题解
前言 这道题比较简单,但我还是想了好一会 题意简述 Abu Tahun很喜欢回文. 一个数组若是回文的,那么它从前往后读和从后往前读都是一样的,比如数组\(\left\{1\right\},\left ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
随机推荐
- Sublime编辑器上的Linux Vim插件常用快捷键
Sublime编辑器上的 Vim 插件常用快捷键 vim 的设置: 在Reference-> User Settings(首选项--> 设置用户) 选项,点击进入配置文件编辑状态,默认的用 ...
- python 字典元素值的乘积
my_dict = {,,} result= for key in my_dict: result=result * my_dict[key] print(result)
- thinkphp3.2笔记(5)创建项目 创建模型 实例化
一 创建项目 1 拷贝框架 目录 public thinkphp .htaccess index.php [application不用拷贝,会自动生成] 2 public 下面创 ...
- 插件uaredirect.js实现电脑版跳转到手机版网站
一.介绍 这段时间,有好多朋友问我,跳转到手机版的那个JS是怎么写的.其实这个JS也不是我写的,是百度siteapp下的一款跳转的产品,使用起来很方便.你可以用这款JS跳转到手机版,也可以跳转到任何你 ...
- Mongo Plugin插件(编辑器PyCharm的Mongo插件安装与使用)
博主接触到MongoDB数据库.用普通的Navicat工具 是不支持的 正准备重新安装一款对应的可视化工具.刚好发现在PyCharm编辑中有连接mongoDB数据的插件 Mongo Plugin 这里 ...
- Oracle linux安装Oracle 11G
Oracle linux安装Oracle 11G 系统环境 Oracle linux 5.8.19.6(64位) Oracle 11.2.0.1(64位) 本文档详细介绍Oracle ...
- App6种常见的数据加载设计
App6种常见的数据加载设计 设计师在进行APP设计的设计时,往往会更加专注于界面长什么样,界面和界面之间怎么跳转,给予用户什么样的操作反馈,却偏偏特别容易忽略掉一个比较重要的环节,就是APP数据加载 ...
- SPOJ COMPANYS Two Famous Companies 最小生成树,二分,思路 难度:2
http://www.spoj.com/problems/COMPANYS/en/ 题目要求恰好有k条0类边的最小生成树 每次给0类边的权值加或减某个值delta,直到最小生成树上恰好有k条边为0,此 ...
- phpstudy2017版本的nginx 支持laravel 5.X配置
之前做开发和学习一直用phpstudy的mysql服务,确实很方便,开箱即用.QQ群交流:697028234 现在分享一下最新版本的phpstudy2017 laravel环境配置. 最新版的phps ...
- linux内存查看工具
这里帮你总结了一下Linux下查看内存使用情况的多种方法~ 在做 Linux 系统优化的时候,物理内存是其中最重要的一方面.自然的,Linux 也提供了非常多的方法来监控宝贵的内存资源的使用情况.下面 ...