解决这个题我的方法有点麻烦,我用了两个映射表,一个是用来保存数组名,以及其长度。另一个是用来保存已经初始化的元素,及其值。但是这里我两个映射表中的元素都设置为string类型,为了好处理。
//d保存定义的数组和其长度,f表示赋值的元素和其值
map<string, string> d, f;
现在我们来看看主函数:
int main() {
string buf; cin >> buf;
while(buf != ".") {
d.clear(); f.clear(); //清空d表和f表
int hang = 0; //表示目前的行,一般请况下为正。
while(buf != ".") {
hang++;
if(buf.find("=") == buf.npos) {
string str, str2;
//Get_Value()自定义的一个函数,主要作用是返回数组名,和数组下标(下标可能是另一个数组)
Get_Value(buf, str, str2);
d[str] = str2;
} else {
size_t a = buf.find("=");
string str = buf.substr(0, a), str2 = buf.substr(a+1);
//judge()也是自定义的一个函数,主要作用判断某个数组元素是否合法,合法返回数组内容,否则返回"-1"
string str3 = judge(str2);
//Print()也是自定义的一个函数,主要作用是打印当前行数,并将其行数设置为负数(后面有用),并且丢弃该组数据剩余的数据
if(str3 == "-1") { Print(hang); break; }
else {
string s1, s2, s3;
Get_Value(str, s1, s2); s3 = judge(s2);
//compare()判断string类型的形参1对应的int值是否比形参2对应的int值大
if(s3 == "-1" || !compare(d[s1], s3)) { Print(hang); break; }
s1 = s1 + "[" + s3 +"]";
f[s1] = str3;
}
}
cin >> buf;
}
//上面行是负数的用处就在这里
if(hang != -1) cout << 0 << endl;
cin >> buf;
}
return 0;
}
首先我们读取函数,我们将输入分为两大类:1. 数组定义。这里不会有什么Bug,所以我们只须将定义的数组的名字和数组长度存入d表中即可。2. 数组元素的赋值。就是这里麻烦,我们举个例子:
b[c[a[n]]]=d[m]
我们需要判断d[m], a[n],c[a[n]] 是否是合法的已经初始化的数组元素(也可能只是个常数),我们还需判断 b[c[a[n]]] 是否合法。
究其根本我们要写一个判断某个数组元素是否合法的函数,怎么样算合法呢?首先这个数组元素的数组名得声明过,其次这个数组元素的下标不能越界。怎么实现呢?我之前想的是利用递归,后来又想了想,既然能用递归,应该也能用栈,况且这个题目又是出现在第5章,肯定是暗示我们使用栈。我先给出其他三个函数:
int compare(string s1, string s2) {
int a = atoi(s1.c_str()), b = atoi(s2.c_str());
return a > b;
}
bool Get_Value(string a, string &b, string &c) {
size_t x = a.find_first_of("["), y = a.find_last_of("]");
if(x == a.npos) return false;
b = a.substr(0, x);
c = a.substr(x+1, y-x-1);
return true;
}
void Print(int &n) {
string buf;
while(cin >> buf && buf != ".");
cout << n << endl; n = -1;
}
现在给出判断合法性的函数
string judge(string buf) {
string s1, s2;
stack<string> s;
//先判断所有的数组名是否都存在,并将其一一入栈
while(Get_Value(buf, s1, s2)) {
if(!d.count(s1)) return "-1";
s.push(s1);
buf = s2;
}
//将数组名一一出栈,结合数组下标判断是否初始化
while(!s.empty()) {
string str = s.top(); s.pop();
str = str + "[" + buf + "]";
if(!f.count(str)) return "-1";
buf = f[str];
}
return buf;
}
这样一来就AC了