真的,看到题目就不想写,因为莫得思路,然后还是写了…
这是到模拟加特判的题
首先要想如何输入,就判断一下是不是第一个字符串就输出“.” 就行啦
第二,储存,本来想用set之类的,最后敲定了map ,想想来个字符串对数字,有觉得字符串转数字不想写,所以就直接存字符串了…例如 da[a] = 15623, 然后对于 a数组的数,可以da[a125] = 123 这样存就ok
第三,就是对那种s[a[b[b[]]]]之类的处理,用递归!如果发现 “[” 后不是数字,则继续找下去,直到有数字,然后判断是否越界和莫得值,若是,则直接bug给值,而返回就返回个空格就行了,因为你又没存过 da[a ]之类的东西,所以会一直bug,回去,就ok了
若成功,返回值就行了,此时要注意第一个还是要表达式的,所以第一个返回表达式,都是传string嘿嘿嘿
第四注意右边正常来讲是数字,所以需要数字专用代码
好上代码,有点丑…
#include <bits/stdc++.h>
using namespace std;
map<string,string> da;
int bug,fir,n;
int val(string s) //判断是不是初始化语句
{
int n = s.size();
for (int i = 0; i < n; i++)
{
if(s[i]=='=') return 0;
}
return 1;
}
string de(string s, int qi)
{
int wei = 0;
string name = "",num = "";
for (int i = qi; i < n; i++)
{
if(s[i]=='[' && !wei){
wei = i+1; name = s.substr(qi,i-qi); i++;
}
if(wei){
if(s[i] >='0' && s[i]<= '9')
{
while(s[i] != ']') i++;
num = s.substr(wei,i-wei);
break;
}
else{
num = de(s,i); break;
}
}
//前面为求左边 那种有表达式 的专用代码
if(s[i] >='0' && s[i]<= '9')
{
num = s.substr(i,n-i);
return num;
} // 求右边一串数字的专用代码
}
//cout<<name<<" "<<num<<endl;
// 一定要注意先判断长度再判断字符串大小!才可完美实现数字比较!
if( da[name] <= num && da[name].size() <= num.size()){
bug = fir; return " "; //返回个空格反正肯定找不到
} //越界
name += num;
if(!qi) return name; //最前面刚开始可以直接表达式
if(!da.count( name )) //莫得值
{
bug = fir; return " ";
}
return da[name]; //否则都要传值
}
int main()
{
string s;
while(1)
{
da.clear(); bug = 0; fir = 0; int ok = 1;
while(cin>>s)
{
n = s.size();
string name,num; int wei = 0;
if(s=="." && fir){
break;
}
else if(s=="." && !fir){
ok = 0; break;
}
else{
fir++; // 第几行程序
if(val(s)){
for (int i = 0; i < n; i++)
{
if(s[i] == '[') {
wei = i; break;
}
} //找位置
name = s.substr(0,wei);
num = s.substr(wei+1,n-wei-2);
da[name] = num; //存下每个 name 的 内存
// cout<<name << " "<<num<<endl;
}
else{
if(bug) continue;
string left = de(s,0),right;
if(bug) continue;
else
{
for (int i = 0; i < n; i++)
if(s[i]=='='){
wei = i+1; break;
}
right = de(s,wei);
}
if(bug) continue;
da[left] = right; //左边 = 右边
// cout<<left <<" "<<right<<endl;;
}
}
}
if(!ok) break;
printf("%d\n",bug);
}
return 0;
}