观摩大牛的代码改的。
题意有两种操作:
1.声明数组: a[4], a[a[b[4]]];
2.给数组赋值: a[4] = a[a[b[4]]];
然后判断第一次出现错误的行.
c++代码
#include<iostream>
#include<map>
#include<vector>
#include<string>
#include<sstream>
#include<cctype>
using namespace std;
typedef long long ll;
pair<char, ll> p; // 数组名 + 下标
map<pair<char,ll>, ll> mp; // 数组名 + 下标 = 赋的值
vector<string> line; // 输入的每一行
map<char,ll> declare; // 数组声明(时数组的大小)
// 把'[', ']'去掉
string cut(string s)
{
char s1[1000];
int j = 0;
for(int i = 0; i<s.size(); i++)
{
if(s[i]!='[' && s[i]!=']')
s1[j++] = s[i];
}
s1[j] = 0;
string s2 = s1;
return s2;
}
// 获得值 eg: a[a[5]], 则传入s="a5", 看a[5]是否存在
ll getValue(string s)
{
string s1 = s;
int tmp = 0;
for(int i = 0; i<s.size(); i++)
{
if(isalpha(s[i]) && !declare.count(s[i])) return -1;
if(isalpha(s[i])) s[i] = ' ';
if(isdigit(s[i]))
{
tmp = i;
break;
}
}
stringstream ss (s);
ll x ;
ss>>x;
for(int i = tmp-1; i>=0; i--)
{
p.first = s1[i]; p.second = x;
if(!mp.count(p)) return -1;
x = mp[p];
}
return x;
}
int main()
{
string s;
while(cin>>s && s[0]!='.')
{
line.clear();
declare.clear();
mp.clear();
line.push_back(cut(s));
int ok = 1;
while(cin>>s && s[0]!='.')
{
line.push_back(cut(s));
}
for(int i = 0; i<line.size(); i++)
{
// 如果是申请数组大小
int k = line[i].find('=');
if(k == std::string::npos)
{
char name = line[i][0];
ll v = getValue(line[i].substr(1));
if(v == -1) { ok = 0; cout<<i+1<<endl; break; }
// 如果申请的数组大小合格
declare[name] = v;
}
// 给数组一个下标 赋值的时候
else
{
char name = line[i][0];
ll x = getValue(line[i].substr(1, k));
ll y = getValue(line[i].substr(k+1));
// 如果存在一个不合格 就gg了
// 1.没有声明 1.不满足值 1.a[x]越界(x>=a.length)
if( !declare.count(name) || x == -1 || y == -1 || x>=declare[name])
{
ok = 0; cout<<i+1<<endl; break;
}
// name[x] = y;
p.first = name; p.second = x;
mp[p] = y;
}
}
if(ok) cout<<0<<endl;
}
}