首页 > 代码库 > UVA 1596 Bug Hunt (大模拟 栈)

UVA 1596 Bug Hunt (大模拟 栈)

题意:

输入并模拟执行一段程序,输出第一个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再入栈)。

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

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

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef pair<char, int> PCI;
  4 map<PCI, int> arr_value; // 数组名和下标, 值
  5 map<char, int> arr_maxi;//数组名 , 最大下标
  6 int F = 0;
  7 int line;
  8 void error()
  9 {
 10     if(!F)
 11     {
 12         F = 1;
 13         cout << line << "\n";
 14     }
 15 }
 16 int read(const string& s, int type)
 17 {
 18     stack<int> name;
 19     stack<int> index;
 20     int k = 0, v = 0;
 21     char a = 0;
 22     if(type == 0)//等于号左边
 23     {
 24         if(!arr_maxi.count(s[0]))//未定义
 25         {
 26             return -1;
 27         }
 28     }
 29     else if(type == 1)//要赋的值
 30     {
 31         if(!arr_maxi.count(s[0]))//未定义
 32         {
 33             return -1;
 34         }
 35     }
 36     for(int i = 2; i <= s.size() - 1; i++)//求出括号内的东西
 37     {
 38         if(isalpha(s[i]))
 39         {
 40             name.push(s[i]);
 41         }
 42         else
 43         {
 44             if(isdigit(s[i]))
 45             {
 46                 int j = i;
 47                 int sum = 0;
 48                 while(isdigit(s[j]))//将字符串转换为十进制数
 49                 {
 50 
 51                     sum *= 10;
 52                     sum += s[j] - 0;
 53                     j++;
 54                 }
 55                 i = j;
 56                 index.push(sum);
 57                 if(index.size() == 1) //此时只有数字
 58                 {
 59                     v = sum;
 60                     break;
 61                 }
 62             }
 63             else
 64             {
 65                 if(s[i] == [)//左括号
 66                 {
 67                     index.push(s[i]);
 68                 }
 69                 else //右括号
 70                 {
 71                     k = index.top();
 72                     index.pop();//下标出栈
 73                     index.pop();//左括号出栈
 74                     a = name.top();
 75                     name.pop(); //名字出栈
 76 
 77                     if(arr_value.count(make_pair(a,k)))//找到a[k]
 78                     {
 79                         if(index.empty())//只剩下这个数
 80                         {
 81                             v = arr_value[make_pair(a,k)];
 82                             break;
 83                         }
 84                         else
 85                         {
 86                             index.push(arr_value[make_pair(a,k)]);
 87                         }
 88                     }
 89                     else//找不到a[k]的值 == 1.a没定义    2. a[k]没赋值
 90                     {
 91                         return -1;
 92                     }
 93                 }
 94             }
 95         }
 96     }
 97     if(type == 0) //等于号左边
 98     {
 99         if(v <= arr_maxi[s[0]]) //小于最大下标
100         {
101             return v;
102         }
103         else
104         {
105             return -3;
106         }
107     }
108     if(type == 1) //要赋的值,
109     {
110         if(!arr_value.count(make_pair(s[0],v)))
111         {
112             return -1;
113         }
114         else
115         {
116             return arr_value[make_pair(s[0],v)];
117         }
118     }
119     if(type == 2)//声明语句
120     {
121         return v;
122     }
123 }
124 int main()
125 {
126     #if LOCAL
127     freopen("1.txt","r",stdin);
128 //    freopen("2.txt","w",stdout);
129     #endif // LOCAL
130 
131     ios::sync_with_stdio(false);
132     string s;
133     while(getline(cin,s) && s[0] != .)
134     {
135 
136         arr_value.clear();
137         arr_maxi.clear();
138         line = 1;
139         F = 0;
140         do
141         {
142             if(s.find(=)!= string :: npos)//赋值语句
143             {
144                 string a,b;
145                 a = s.substr(0,s.find(=));
146                 b = s.substr(s.find(=)+1);
147                 int value ,flag = 0;
148                 if(isdigit(b[0]))//如果第一个是数字,那么只有数字
149                 {
150                     flag = 1;
151                     int sum = 0;
152                     for(int i = 0; i < b.size(); i++)
153                     {
154                         sum *= 10;
155                         sum += b[i] - 0;
156                     }
157                     value =http://www.mamicode.com/ sum;
158                 }
159                 else//第一个是字母
160                 {
161                     value= http://www.mamicode.com/read(b,1);//先读取要赋的值
162                 }
163                 if(value < 0)//错误
164                 {
165                     error();
166                 }
167                 int index = read(a,0);
168                 if (index < 0)
169                 {
170                     error();
171                 }
172                 arr_value[make_pair(s[0],index)] = value;
173 
174             }
175             else //声明语句
176             {
177                 int v = read(s,2);
178                 if (v < 0)
179                 {
180                    error();
181                 }
182                 else
183                 {
184                     arr_maxi[s[0]] = v - 1;
185                 }
186             }
187             line ++;
188         }while(getline(cin , s) && s[0] != .);
189         if(!F)//读到最后都没发现错误
190         {
191             cout <<"0\n";
192         }
193     }
194 }

 

UVA 1596 Bug Hunt (大模拟 栈)