UVa 1596 Bug Hunt易错的地方

解决这个题我的方法有点麻烦,我用了两个映射表,一个是用来保存数组名,以及其长度。另一个是用来保存已经初始化的元素,及其值。但是这里我两个映射表中的元素都设置为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了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值