话说有这样一道神题:【集训队互测2015】未来程序·改

大意是要求写一个简单的C++解释器!这里去掉了C++的许多特性,连简单的breakcontinue都没有了!

话说NOI被屠了之后,一时心血来潮,打算A了这道题。最近的一个星期闲着无聊(其实还是很多事要做),在历经险阻之后,终于A掉这道丧心病狂的OI题。

虽然我没有看过任何关于解释器的理论,但我觉得好像还是可以凭自己乱搞出来的,于是便开始了这长达一周的旅程。估计写了4h的代码,调试2h。

听说可以用语言分析树这样高大的东西来做,我看到其他A了的3个人就是用这样的东西的。Orz,以后有机会找来学学。

我认为我的代码有三个最主要的部分,实现了之后发现写掉这题也不算太难。

变量储存

就是将单个的变量和数组储存起来的一个东西。最最困难的一个地方是有些变量重名,但是不是同一个量,比如:

int i;
i = 10;
if (i) {
int i;
i = 0;
if (i) {
cout << 1;
}
else cout << 0;
}

这里的i就是不一样的,运行后输出0

我是用了map<string, stack<Variable> >,来保存的,每次遇到左大括号时标记一下,遇到右大括号就清理一下。由于变量的读写是非常普遍的,而在这里由使用了map,所以导致了程序运行速度慢,不管啦,反正可以过就可以了,其实可以用hash代替。

语句执行

主要的思想是维护一些光标(我管它叫光标),光标就是一个变量,保存着程序运行到哪里。

首先要把所有的函数都预先找到它们的位置,然后写两个函数:

  • Return runStatement(int startPosition);
  • Return runFunction(int startPosition, const vector<int> &params);

这里Return是一个结构体,记录返回的值、返回的命令(return,continue,break,虽说这里没有后面两个)以及运行完这个语句/函数后到哪个位置。

至于怎么写runStatement,就主要靠下面的了。

表达式计算

一个经典的方法就是运用栈,一个符号栈,一个变量栈。

下面是一些主要的问题和解决方法:

  • 正号和负号怎么处理?
  • 预处理下,把+(正号,不是加号)变为$+。并且注意它们是右结合的。
  • 有右结合的运算符,比如=
  • 当有一个新符号加入时,我们通过这样的判断就能解决这个问题:while (levelCur < levelTop || (levelCur == levelTop && ! rightCombine(opt))) ...
  • cout这些特殊的怎么处理?
  • 我们只需要标记一下就可以了(把它作为一个特殊变量)。
  • 数组和函数的参数怎么处理?
  • 比如f(1, 3, 2, 5),我们把f当作一个右结合的四目运算符就可以了。

然后写好了这些我们就可以快乐地AC了!

代码链接。感觉用C++写C++解释器有点逗呢。

如何A掉未来程序改的更多相关文章

  1. uoj98未来程序改 纯暴力不要想了

    暴力模拟A了,数据还是良(shui)心(shui)的 90分的地方卡了半天最后发现一个局部变量被我手抖写到全局去了,,, 心碎*∞ 没什么好解释的,其实只要写完表达式求值(带函数和变量的),然后处理一 ...

  2. bzoj4020: 未来程序·改

    只需写一个解释器 第一次预处理将输入进行分词,分割出 关键字,运算符,变量/函数名,整数常量,并对变量/函数名离散化以便处理 第二次预处理建语法树,每个节点存节点类型,变量定义表等信息 运行时在语法树 ...

  3. 问题-某个程序改了ICO图标后编译后还是显示老图标?

    问题现象:某个程序改了ICO图标后编译后还是显示老图标? 问题原原:可能是因为系统的缓存问题. 问题处理:把程序的EXE放在别的路径下打开就可以了. 问题相关人员:QQ253120114(朋友)  Q ...

  4. uoj#73 【WC2015】未来程序

    在 2047 年,第 64 届全国青少年信息学奥林匹克冬令营前夕,B君找到了 2015 年,第 32 届冬令营的题目来练习. 他打开了第三题 “未来程序” 这道题目: 本题是一道提交答案题,一共 10 ...

  5. Uoj 73 未来程序

    Uoj 73 未来程序 神仙提答. Subtask 1 仔细阅读,发现是要计算 \(a*b\ \%\ c\).用龟速乘或者 \(python\) 直接算. Subtask 2 仔细阅读并手算一下,发现 ...

  6. 昨晚值班将发dla的程序改好后放入正式环境

    可是在修改的topic的发送文件中出现有节点没有对应,整个过程陆续调至有20分钟最后11电把新程序换掉.

  7. VS2013中,将Qt的GUI程序改为控制台程序

    在Visual studio 中创建QT GUI程序是不带Console的,但是调试时候常常需要查看打印信息,可以通过如下设置显示控制台 方法一.在vs中直接创建控制台程序方法二.当你通过设置你的应用 ...

  8. 四则运算程序扩展:将程序改为java语言,并允许用户输入,对输入结果进行验证

    题目 每个同学选一个方向,把程序扩展一下:1.让程序能接受用户输入答案,并判定对错.最后给出总共对/错 的数量.2.把程序变成一个网页程序,用户通过设定参数,就可以得到各种题目.3.把程序变成一个Wi ...

  9. 小程序--改变子级别页面导航栏信息 / navigationBarTitleText

    微信小程序在公共文件app.json中设置了导航栏相关样式如下: 其中  navigationBarTitleText 为设置导航栏名称,若是想子级页面和父页面的header页面不同,则在子级文件中新 ...

随机推荐

  1. 浅谈RFID电子标签封装技术

    1RFID技术概述 1.1RFID技术概念 RFID是RadioFrequencyIdentification的缩写,即射频识别技术,俗称电子标签.RFID射频识别是一种非接触式的自动识别技术,它通过 ...

  2. Qt之美(一):d指针/p指针详解

    Translated  by  mznewfacer   2011.11.16 首先,看了Xizhi Zhu 的这篇Qt之美(一):D指针/私有实现,对于很多批评不美的同路人,暂且不去评论,只是想支持 ...

  3. Qt多线程编程总结(一)(所有GUI对象都是线程不安全的)

    Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法. 这个文档是提供给那些对多线程编程有丰富的知识和经验的听众的.推荐阅 ...

  4. samba服务器上文件名大小写

    samba服务器上文件名大小写 如果给HP_UX配置samba之后,通过windows访问有时候会发现文件名大小写不对时,请注意下述配置信息是否正确.在/etc/opt/samba/smb.conf中 ...

  5. VC++6.0中各种文件的作用

    VC++ 6.0是一款很经典的C/C++开发工具,虽然是1998年的东西了,但是现在使用依然很广!在用它开发的时候,会发现在建立的工程的文件夹里面,有很多文件,各种后缀名.在这里呢,我主要说一下各个文 ...

  6. Android项目导入时,出现的Could not write file 。。。。。。.classpath错误解决办法

    导入到Eclipse中后选择了相应的API后,红叉的项目错误没有了. 工程列表也无任何错误了.但出现了这样的提示框错误 说明的是.classpath这个环境文件不能写.随后,查看工程文件主目录下的.c ...

  7. Session、SessionId和Cookie的关系

    Session是保存在服务器中的,SessionId是保存在Cookie中的. 当用户·登录时候,系统会将"用户名"和"密码"保存到Session中,系统会给每 ...

  8. Xcode - 详解真机测试步骤

    第一种从iOS9.0之后推出的免费开发者账号 1.注册开发者 * 注册Apple ID * 使用Apple ID登录苹果开发者中心,注册成为开发者 * 此过程为免费,只是为了让普通的Apple ID具 ...

  9. mysql时间与字符串相互转换

    时间.字符串.时间戳之间的互相转换很常用,但是几乎每次使用时候都喜欢去搜索一下用法:本文整理一下三者之间的 转换(即:date转字符串.date转时间戳.字符串转date.字符串转时间戳.时间戳转da ...

  10. HDU 4548(美素数)

    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Description 小明对数的 ...