UVA ~ 1596 ~ Bug Hunt (字符串处理 + map)

题意:输入并模拟执行一段程序,输出第一个BUG所在的行。每行程序有两种可能:

1.数组定义,格式为arr[size]。例如a[10]或者b[5],可用下标分别是0~9和0~4.定义之后所有元素均为未初始化状态。

2.赋值语句,格式为arr[index] = value。例如a[0] = 3或者a[a[0]] = a[1].

定义语句保证正确,赋值语句可能会出现两种bug:下标index越界;使用未初始化的变量(index和value都可能会出现这种情况)

数组名保证为一个字符(a~z,A~Z),题目中出现的常数保证在0 ~ 2^31 − 1 (= 2147483647)范围之内。

程序不超1000行,每行不超过80个字符,一共不超过1500行。

思路:用一个map保存数组名对应其长度,一个map保存一段字符串对应的值。数组定义,我们直接放入map对应长度即可。赋值语句,判断"="右边的值是否被定义,"="左边的第一个[]内的值是否被定义且小于数组长度。判断的时候因为有多重括号,所以我们要一层一层的判断,先递归进入到最后一层即只有一个括号或者没括号,然后一层一层的往外返回值,如果中间某一层该值不存在返回-1就可以,因为[-1]一定不存在所以后面一定返回的都是-1。

感觉这题的输入反人类。。。我是用一个vector先把每段程序的输入保存下来,然后再去处理。


#include<bits/stdc++.h>
using namespace std;
map<char, int> len;//数组名,长度
map<string, int> val;//字符串,对应值
vector<string> v;//代码
int get_val(string str)//递归求str这段字符串对应的值,不存在对应-1
{
    if (str.find('[') == string::npos) return stoi(str);//没有括号
    if (count(str.begin(), str.end(), '[') == 1)//还有一对括号
    {
        if (!val.count(str)) return -1;//该字符串没有出现过
        return val[str];
    }
    if (count(str.begin(), str.end(), '[') >= 2)//还有两对及以上的括号
    {
        int v = get_val(str.substr(str.find('[') + 1, str.rfind(']') - str.find('[') - 1));//递归
        if (!val.count(str.substr(0, 2) + to_string(v) + ']')) return -1;//该字符串没有出现过
        return val[str.substr(0, 2) + to_string(v) + ']'];
    }
}
int main()
{
    string str;
    while (getline(cin, str) && str[0] != '.')
    {
        v.clear(); len.clear(); val.clear();
        v.push_back(str);
        while (getline(cin, str) && str[0] != '.') v.push_back(str);

        int bug = 1;//BUG行数
        for (auto i: v)
        {
            if (i.find("=") == string::npos)//没有等号,定义数组
            {
                len[i[0]] = stoi(i.substr(2));
            }
            else 
            {
                string l = i.substr(0, i.find('='));//左边
                string r = i.substr(i.find('=') + 1);//右边
                int lval = get_val(l.substr(l.find('[') + 1, l.rfind(']') - l.find('[') - 1));//左值
                int rval = get_val(r);//右值
                if (lval == -1 || rval == -1 || !len.count(i[0]) || lval >= len[i[0]]) break;
                string name = i.substr(0, 2) + to_string(lval) + ']';
                val[name] = rval;//该值放入map
            }
            bug++;
        }
        if (bug > v.size()) bug = 0;//如果最后一行都没有BUG
        cout << bug << endl;
    }
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值