In this problem, we consider a simple programming language that has only declarations of one-dimensional integer arrays and assignment statements. The problem is to find a bug in the given program.

The syntax of this language is given in BNF as follows:

<program> ::= <declaration> | <program><declaration> | <program><assignment>
<declaration> ::= <array_name>[<number>]<new_line>
<assignment> ::= <array_name>[<expression>]=<expression><new_line>
<expression> ::= <number> | <array_name>[<expression>]
<number> ::= <digit> | <digit_positive><digit_string>
<digit_string> ::= <digit> | <digit><digit_string>
<digit_positive> ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<digit> ::= 0 | <digit_positive>
<array_name> ::= a | b | c | d | e | f | g | h | i | j | k | l | m |n | o | p | q | r | s | t | u | v | w | x | y | z |A | B | C | D | E | F | G | H | I | J | K | L | M |N | O | P | Q | R | S | T | U | V | W | X | Y | Z

where <new_line> denotes a new line character (LF).

Characters used in a program are alphabetical letters, decimal digits, =, [, ] and new line characters. No other characters appear in a program.

A declaration declares an array and specifies its length. Valid indices of an array of length n are integers between 0 and n - 1, inclusive. Note that the array names are case sensitive, i.e. array a and array A are different arrays. The initial value of each element in the declared array is undefined.

For example, array a of length 10 and array b of length 5 are declared respectively as follows.

a[10]
b[5]

An expression evaluates to a non-negative integer. A <number> is interpreted as a decimal integer. An <array_name>[<expression>] evaluates to the value of the <expression>-th element of the array. An assignment assigns the value denoted by the right hand side to the array element specified by the left hand side.

Examples of assignments are as follows.

a[0]=3
a[1]=0
a[2]=a[a[1]]
a[a[0]]=a[1]

A program is executed from the first line, line by line. You can assume that an array is declared once and only once before any of its element is assigned or referred to.

Given a program, you are requested to find the following bugs.

  • An index of an array is invalid.

  • An array element that has not been assigned before is referred to in an assignment as an index of array or as the value to be assigned.

You can assume that other bugs, such as syntax errors, do not appear. You can also assume that integers represented by <number>s are between 0 and 231 - 1 (= 2147483647), inclusive.

 

Input

The input consists of multiple datasets followed by a line which contains only a single ‘.’ (period). Each dataset consists of a program also followed by a line which contains only a single ‘.’ (period). A program does not exceed 1000 lines. Any line does not exceed 80 characters excluding a new line character.

 

Output

For each program in the input, you should answer the line number of the assignment in which the first bug appears. The line numbers start with 1 for each program. If the program does not have a bug, you should answer zero. The output should not contain extra characters such as spaces.

 

Sample Input

a[3]
a[0]=a[1]
.
x[1]
x[0]=x[0]
.
a[0]
a[0]=1
.
b[2]
b[0]=2
b[1]=b[b[0]]
b[0]=b[1]
.
g[2]
G[10]
g[0]=0
g[1]=G[0]
.
a[2147483647]
a[0]=1
B[2]
B[a[0]]=2
a[B[a[0]]]=3
a[2147483646]=a[2]
.
.

Sample Output

2
2
2
3
4
0 玩的又是字符串!!!要疯!!! 写了一半,实在是不会用stack啊啊啊啊啊
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <sstream>
using namespace std; map<string,int> zhi; stack<char>s; string change(char t)
{
char ss[];
ss[] = t;
ss[] = '\0';
return ss;
} void deal_dingyi(string exp)
{
int n = exp.length();
string t1;
stringstream ss;
if(isalpha(exp[]))t1 = change(exp[]);
int range,x1 = ,x2;
for(int i = ;i < n; i++){
if(exp[i] <''&& exp[i] > ''){
if(!x1)x1 = i;
if(exp[i+] == ']'){
x2 = i - ;
break;
}
}
}
//cout<<"x1 "<<x1<<"x2 "<<x2<<endl;
string t2 = exp.substr(x1,x2);
//cout<<t2<<endl;
ss.str(t2);
ss >> range;
zhi[t1] = range;
} bool deal_fuzhi(string exp)
{ int n = exp.length();
stringstream ss;
if(!(exp.find('=') < n &&exp.find('=') >= ))deal_dingyi(exp); //定义数组的存储
else{
for(int i = ;i <= n; i++){ }
} return false;
} int main()
{
string exp;
while(cin >> exp){
if(exp == ".")break;
int n = ; //计数第几行
deal_fuzhi(exp);//if(!)cout << n++ <<endl;
while(cin>>exp){
if(exp == ".")break;
if(!deal_fuzhi(exp))cout << n++ <<endl;
}
}
system("pause");
return ;
}

那就不用stack,想想其他方法。

结果想了想其他,应该是要用递归做的,然而递归也不太会,好难过......

最后看别人的代码,好不容易把递归整了出来。但感觉还是不能完全理解递归,需要好好琢磨

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <map>
#include <sstream>
using namespace std; map<string,long long> zhi;
map<string,string>val;
bool bug; string change(char t)
{
char ss[];
ss[] = t;
ss[] = '\0';
return ss;
} void deal_arry(string exp) //存储数组定义
{
int n = exp.length();
string t1;
stringstream ss;
long long range;
t1 = exp.substr(,exp.find('['));
string t2 = exp.substr(exp.find('[')+,exp.find_last_of(']')-);
ss.str(t2);
ss >> range;
//cout<<range<<"///"<<endl;
zhi[t1] = range;
} string deal_index(string exp,string arry)
{
long long t = ;
string y, z;
//cout<<"!"<<exp<<endl;
if(exp.find("[") == string::npos){ //exp为数字
stringstream ss(exp);
ss >> t;
//cout<<endl<<arry<<"+"<<zhi[arry]<<"+"<<t<<endl;
if( arry != "\0" &&t >= zhi[arry]){
//cout<<"*1*"<<endl;
bug = true;
}
return exp;
}
y = exp.substr(, exp.find_first_of("["));
z = exp.substr(exp.find("[")+, exp.find_last_of("]") - );
//cout<<"z "<<z <<endl;
//cout<<" y "<<y<<endl;
z = deal_index(z, y);
if(bug) return "/0" ;
exp = y + "[" + z + "]";
if( !val.count(exp) ) bug = ;
return val[exp]; } int main()
{
string exp;
int n = ;
bool mark = false;
while(cin >> exp){
if(exp == "."){
val.clear();
zhi.clear();
if(mark)break;
else{
if(!bug)cout<<<<endl;
n = ; //计数第几行
bug = false;
mark = true;
}
}
else{
mark = false;
if(bug)continue;
if(exp.find('=') == string::npos){ //find函数找不到字符返回" string::npos "
deal_arry(exp);
}
else{
string index, arry1, value, arry2,s;
s = exp.substr(,exp.find('='));
//cout << s<<"%"<<endl;
index = s.substr(s.find('[')+,s.find_last_of(']')-); //数组第几个数
arry1 = s.substr(,s.find('[')); //数组
value = exp.substr(exp.find('=')+); //数组存储的值
//cout << index <<"@"<<endl;
index = deal_index(index,arry1);
stringstream ss(index);
long long t;
ss >> t;
if( t>= zhi[arry1]){
bug = true; //数组越界
} string left_value = arry1+'['+index+']';
value = deal_index(value, "\0");
if(bug)cout <<n <<endl;
else {
val[left_value] = value;
}
}
n++;
}
}
// system("pause");
return ;
}

以下是别人的代码,看了看改了改,是用stack做的

话说写的真的很棒

#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <sstream>
#include <fstream>
#include <stack> using namespace std; map<string, long long> array_table;
map<string,map< long long, long long>> array_value_table; //string数组的下标为int的位置的值为int #define FILE void partition(string origin,string &left,string &right) //把式子等号两边分开
{
int index = origin.find_first_of('=',);
cout << "index "<<index<<endl;
if(index != -){ //有等号 赋值
left = origin.substr(,index);
right = origin.substr(index+);
}
else{ //无等号 定义
left = origin;
right = "";
}
} void getArray(string str,string &name, string &value) //把数组字母与[]内数字分开
{
int begin = str.find_first_of('[',);
int end = str.find_last_of(']');
if(begin != -) //有[ 是数组
{
name = str.substr(,begin);
value = str.substr(begin+,end-begin-);
}
else //无[ 不是数组—常量或者字母
{
name = "";
value = str;
}
} long long calculateArray(string str)
{
string name,value;
getArray(str,name,value);
stack<string> s;
long long ans;
while(name!=""){ //只剩下[]内的数字时 停止
string left,right;
getArray(value,left,right); if (array_table.count(name) == )return -; //无此数组的定义 value = right;
s.push(name);
name = left; }
ans = atoi(value.c_str());
if(ans<) return -; //数组下标小于0
while (!s.empty())
{
string left = s.top();
long long num = array_table[left];
if(ans >= num) return -; //数组下标超出数组范围
if(array_value_table[left].count(ans) == )return -; //数组下标为 ans 的数未定义
ans = array_value_table[left][ans];
s.pop();
}
return ans;
} int main(int argc, char* argv[])
{ #ifdef FILE
ifstream in("data.txt");
ofstream out("output.txt");
cin.rdbuf(in.rdbuf());
cout.rdbuf(out.rdbuf());
#endif string str;
bool mark = false,isfirst = true;
int num = ; while(cin>>str)
{
if(str!=".")
{
mark = false;
num++;
string left,right;
partition(str,left,right); if(right=="") //定义数组
{
string name,value;
getArray(left,name,value);
array_table[name] = atoi(value.c_str()); //atoi将字符串转化为整型
} else //赋值语句
{
string name, value;
long long ans,temp;
getArray(left,name,value);
temp = calculateArray(value); //value为数组下标
ans = calculateArray(right); //赋给数组的值
if(temp >= && temp < array_table[name]&& ans != -){
array_value_table[name][temp] = ans;
}
else{
if(isfirst){
cout<<num<<endl;
isfirst = false;
}
}
}
}
else
{
array_table.clear();
array_value_table.clear();
if(mark)
break;
else
{
if(isfirst)
cout<<<<endl;
mark = true;
isfirst = true;
num = ;
}
}
}
//system("pause");
return ;
}
												

uva 1596 Bug Hunt的更多相关文章

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

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

  2. UVA 1596 Bug Hunt (大模拟 栈)

    题意: 输入并模拟执行一段程序,输出第一个bug所在的行. 每行程序有两种可能: 数组定义: 格式为arr[size]. 例如a[10]或者b[5],可用下标分别是0-9和0-4.定义之后所有元素均为 ...

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

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

  4. UVa 1596 Bug Hunt (STL栈)

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

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

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

  6. [刷题]算法竞赛入门经典(第2版) 5-9/UVa1596 - Bug Hunt

    //开学了,好烦啊啊啊啊啊!怎么开个学那么多破事情!!都俩星期了,终于有时间写出来一道题 题意:不难理解,不写了.这几天忙的心累. 代码:(Accepted, 0.010s) //UVa1596 - ...

  7. Bug Hunt UVA - 1596

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

  8. 【习题 5-9 UVA - 1596】Bug Hunt

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] map模拟 map<string,int>记录每个数组的大小 map <pair<string, int&g ...

  9. 在iOS上使用ffmpeg播放视频

    国外靠谱的有这几个:1.Mooncatventures group https://github.com/mooncatventures-group 2.KxMoviePlayer (use Open ...

随机推荐

  1. Mac系统cocos2dx + android 开发环境配置

    Mac系统cocos2dx + android 开发环境配置 /****************************************************** 这遍文章主要转载自:htt ...

  2. 给软件增加注册功能 c#

    1.软件注册类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  3. (原)torch中显示nn.Sequential()网络的详细情况

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6065526.html 本部分多试几次就可以弄得清每一层具体怎么访问了. step1. 网络定义如下: ...

  4. 在Eclipse中运行Nutch2.3

    参考http://wiki.apache.org/nutch/RunNutchInEclipse 一.环境准备 1.下载nutch2.3源代码 wget http://mirror.bit.edu.c ...

  5. linux管理员切换与管理员密码第一次设置

    在终端输入su - root回车来切回到超级管理员,Ubuntu的默认超级管理员root密码是随机的,即每次开机都有一个新的root密码.我们可以在终端输入命令 sudo passwd,然后输入当前用 ...

  6. destoon实现资讯信息前面调用它所属分类的方法

    有时候我们需要在一些信息前面添加他所属的分类,让他显示出来,本文介绍的方法虽然有些不具有通用性,但是可以实现这一效果,代码如下,供大家参考: <!--{php null=tag("mo ...

  7. python之简单入门01

     python简单的介绍使用: 一.个人感觉写Python程序,最好用的工具就是pycharm了,自动补全功能可以满足大多数不太喜欢记忆的人群: 安装pycharm之前应该先安装python解释器,目 ...

  8. JAVA单元测试Junit

    1.为什么要用Junit 做了很多项目,几乎没怎么用过Java的单元测试,是因为它没有用吗?显然不是,是自己的开发方式太不规范!对于大型的软件项目,单元测试不仅有效实用,还非常有必要!它能够测试每个方 ...

  9. C语言内存分配函数

    c语言标准库提供了3个内存分配的函数,都包含在头文件<stdlib.h>中 1.malloc 函数原型: void *malloc( size_t size ); 参数:要分配内存大小的字 ...

  10. (摘) MDI登陆问题

    MDI编程中需要验证用户身份,那么登陆窗口就需要在验证密码后进行相关的隐藏处理. (1)隐藏登陆窗口(登陆窗体作为启动) 登陆按钮事件:this.Hide();//隐藏登陆窗口MDI_Name M = ...