题意:

输入并模拟执行一段程序,输出第一个bug所在的行。

每行程序有两种可能:

数组定义:

格式为arr[size]。

例如a[10]或者b[5],可用下标分别是0~9和0~4。定义之后所有元素均为未初始化状态。

赋值语句:

格式为arr[index]=value。

或者arr[index] = arr[arr[index]]。

例如a[0]=3或者a[a[0]]=a[1]。

赋值语句和数组定义可能会出现两种bug:

下标index越界;

使用未初始化的变量(index和value都可 能出现这种情况。

程序不超过1000行,每行不超过80个字符且所有常数均为小于2 31的非负整数。

分析:

可以分为3种情况考虑:

首先考虑开以下两个map

声明语句:

对于①: 那么"a["与最后的"]"都是肯定存在的, 所以声明语句的a是肯定合法的,只需要判断...能不能转化为一个值num即可,如果可以转换为一个值就是语句就是合法的

arr_maxi[a] = num;

赋值语句:

对于②:需要赋值部分,判断条件

  1.需要去找一下a有没有定义,

  2.判断...能不能转化一个值num,

  3.num有没大于a的最大下标,

对于③:值部分,判断条件

  1.b有没有定义

  2.“...”能不能转化为一个值num

  3.b[num]有没有初始化

如果②③都满足了, 那么这句赋值语句就是合法的,插入  arr_value[pair(数组名,下标)] = 值

现在问题就是,如何判断...能不能转化为一个值

我的方法是使用栈,首先明确, 每条语句只有:大小写字母,[,],数字,四种情况

那么可以开一个 字母栈  一个其他栈

然后遇到字母就将字母入字母栈 遇到其他就入其他栈(这里要注意将字符串的数字转化为int再入栈)。

入其他栈有一个类似括号匹配的过程,

如果碰到“]”,那么就一直出栈直到遇到“[’, 那么中间遇到的那个数字就是,数组名为字母栈顶,下标为这个数字的值, 如果这个值存在, 那么就将这个值入栈, 直到其他栈最后只剩下一个值,没有其他元素。

 #include <bits/stdc++.h>
using namespace std;
typedef pair<char, int> PCI;
map<PCI, int> arr_value; // 数组名和下标, 值
map<char, int> arr_maxi;//数组名 , 最大下标
int F = ;
int line;
void error()
{
if(!F)
{
F = ;
cout << line << "\n";
}
}
int read(const string& s, int type)
{
stack<int> name;
stack<int> index;
int k = , v = ;
char a = ;
if(type == )//等于号左边
{
if(!arr_maxi.count(s[]))//未定义
{
return -;
}
}
else if(type == )//要赋的值
{
if(!arr_maxi.count(s[]))//未定义
{
return -;
}
}
for(int i = ; i <= s.size() - ; i++)//求出括号内的东西
{
if(isalpha(s[i]))
{
name.push(s[i]);
}
else
{
if(isdigit(s[i]))
{
int j = i;
int sum = ;
while(isdigit(s[j]))//将字符串转换为十进制数
{ sum *= ;
sum += s[j] - '';
j++;
}
i = j;
index.push(sum);
if(index.size() == ) //此时只有数字
{
v = sum;
break;
}
}
else
{
if(s[i] == '[')//左括号
{
index.push(s[i]);
}
else //右括号
{
k = index.top();
index.pop();//下标出栈
index.pop();//左括号出栈
a = name.top();
name.pop(); //名字出栈 if(arr_value.count(make_pair(a,k)))//找到a[k]
{
if(index.empty())//只剩下这个数
{
v = arr_value[make_pair(a,k)];
break;
}
else
{
index.push(arr_value[make_pair(a,k)]);
}
}
else//找不到a[k]的值 == 1.a没定义 2. a[k]没赋值
{
return -;
}
}
}
}
}
if(type == ) //等于号左边
{
if(v <= arr_maxi[s[]]) //小于最大下标
{
return v;
}
else
{
return -;
}
}
if(type == ) //要赋的值,
{
if(!arr_value.count(make_pair(s[],v)))
{
return -;
}
else
{
return arr_value[make_pair(s[],v)];
}
}
if(type == )//声明语句
{
return v;
}
}
int main()
{
#if LOCAL
freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
#endif // LOCAL ios::sync_with_stdio(false);
string s;
while(getline(cin,s) && s[] != '.')
{ arr_value.clear();
arr_maxi.clear();
line = ;
F = ;
do
{
if(s.find('=')!= string :: npos)//赋值语句
{
string a,b;
a = s.substr(,s.find('='));
b = s.substr(s.find('=')+);
int value ,flag = ;
if(isdigit(b[]))//如果第一个是数字,那么只有数字
{
flag = ;
int sum = ;
for(int i = ; i < b.size(); i++)
{
sum *= ;
sum += b[i] - '';
}
value = sum;
}
else//第一个是字母
{
value= read(b,);//先读取要赋的值
}
if(value < )//错误
{
error();
}
int index = read(a,);
if (index < )
{
error();
}
arr_value[make_pair(s[],index)] = value; }
else //声明语句
{
int v = read(s,);
if (v < )
{
error();
}
else
{
arr_maxi[s[]] = v - ;
}
}
line ++;
}while(getline(cin , s) && s[] != '.');
if(!F)//读到最后都没发现错误
{
cout <<"0\n";
}
}
}

UVA 1596 Bug Hunt (大模拟 栈)的更多相关文章

  1. UVa 1596 Bug Hunt (string::find && map && 模拟)

    题意 : 给出几组由数组定义与赋值构成的编程语句, 有可能有两种BUG, 第一种为数组下标越界, 第二种为使用尚未定义的数组元素, 叫你找出最早出现BUG的一行并输出, 每组以' . '号分隔, 当有 ...

  2. 【UVA】1596 Bug Hunt(模拟)

    题目 题目     分析 算是个模拟吧     代码 #include <bits/stdc++.h> using namespace std; map<int,int> a[ ...

  3. UVa 1596 Bug Hunt (STL栈)

    题意:给定两种操作,一种是定义一个数组,另一种是赋值,让你找出哪一步时出错了,出错只有两种,一种是数组越界,另一种是访问未定义变量. 析:当初看到这个题时,感觉好麻烦啊,然后就放过去了,而现在要重新回 ...

  4. 【技巧性(+递归运用)】UVa 1596 - Bug Hunt

    In this problem, we consider a simple programming language that has only declarations of onedimensio ...

  5. uva 1596 Bug Hunt

    In this problem, we consider a simple programming language that has only declarations of one-dimensi ...

  6. KEILC51可重入函数及模拟栈浅析

    MARK:文章中的红色部分是个人的理解. KEILC51可重入函数及模拟栈浅析 关键字:keilc51,模拟堆栈,可重入函数调用,参数传递,C?XBP,C?ADDXBP 摘要:本文较详细的介绍了kei ...

  7. NOIP2017 时间复杂度 大模拟

    再写一道大模拟题. 由于是限时写的,相当于考场代码,乱的一批. 题目链接:P3952 时间复杂度 先记几个教训: 字符串形式的数字比较大小老老实实写函数,字典序都搞错几次了 栈空的时候不但pop()会 ...

  8. Java连载69-接受输入、用数组模拟栈

    一.编写一个酒店管理系统 1.直接上代码 package com.bjpowernode.java_learning; ​ public class D69_1_ { //编写一个程序模拟酒店的管理系 ...

  9. java模拟栈的操作

    栈是一种有序列表,可以使用数组的结构来储存栈的数据内容 思路 1. 创建一个栈类StackArray 2. 定义一个top来模拟栈顶,初始化为-1 3. 入栈: 当有数据加入到栈的时候 top++ s ...

随机推荐

  1. _bzoj1208 [HNOI2004]宠物收养所【Splay】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1208 以后在空间限制允许的情况下我绝对不纠结内存占用问题啦!就因为不舍得用long long ...

  2. 【洛谷4769】[NOI2018] 冒泡排序(动态规划_组合数学)

    题目: 洛谷 4769 博客页面左下角的嘴嘴瓜封神之战中的题目 分析: 一个排列交换次数为 \(\frac{1}{2}\sum_{i=1}^{n}|i-p_i|\) 的充要条件是这个排列不存在长度为 ...

  3. 题解报告:poj 2533 Longest Ordered Subsequence(最长上升子序列LIS)

    Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence ...

  4. Service官方教程(11)Bound Service示例之2-AIDL 定义跨进程接口并通信

    Android Interface Definition Language (AIDL) 1.In this document Defining an AIDL Interface Create th ...

  5. 【先定一个小目标】Postgresql允许远程访问配置修改

    1.解决不能连接远程postgresql: postgresql默认情况下,远程访问不能成功,如果需要允许远程访问,需要修改两个配置文件,说明如下: 1.postgresql.conf 将该文件中的l ...

  6. js promise 介绍和使用

    1.什么是promise js是单线程执行的. ajax是典型的异步操作,我们通常会在ajax的成功或者失败之后写上回掉函数.这中写法是一种嵌套的方式,如果回掉多了会造成代码复杂并且难以复用. pro ...

  7. JS filters-ul li简单过滤

    功能要求:在input中输入字母,显示ul li中匹配的元素,隐藏不匹配的 <!DOCTYPE html> <html> <head> <meta chars ...

  8. 短视频SDK简单易用——来自RDSDK.COM

    锐动天地为开发者提供短视频编辑.视频直播.特效.录屏.编解码.视频转换,等多种解决方案,涵盖PC.iOS.Android多平台.以市场为导向,不断打磨并创新技术,在稳定性,兼容性,硬件设备效率优化上千 ...

  9. Godaddy域名301跳转问题处理

    前言:Godaddy的域名301跳转一共有六步,详情见以下步骤: 第一步: 第二步:找到你的域名,并点击DNS 第三步:点击添加 第四步:添加解析ip地址 第五步:域名转址,也就是301跳转 第六步: ...

  10. InChatter系统之服务端的Windows服务寄宿方式(三)

    为了部署的方便,我们开发Windows服务的服务寄宿程序,这样我们的服务便可以作为系统服务,随着系统的启动和关闭而启动和关闭,而避免了其他的设置,同时在服务的终止时(如系统关闭等)能及时处理服务的关闭 ...