跳转至

CF195C Try and Catch 题解

洛谷题面 | Codeforces 题面

因为洛谷爬虫太逊了,你需要注意到样例输入输出里面异常显示了 ",请在测样例的时候把它们换成 "

这道题很有意思,题目让我们实现一个 try-catch 处理程序。给定的这个程序里面只会执行一次 throw 抛出异常,我们需要确定哪一个 catch 语句捕获到了这个异常(若没有输出 Unhandled Exception)。

首先,我们开一个栈存储每一个 try 语句的位置(以便在遇到 catch 时找到对应的 try),之后定义一个字符串和一个整数代表抛出异常的名称和位置。

1
2
3
stack<int> st;
string ts;
int tp;

读入每一行时,我们判断当前读入的语句是哪种类型:

  • try:将当前行号压入栈。
  • throw:更新一下抛出异常的名称和位置。
  • catch:读取栈顶元素(对应的 try 语句的位置),若:
  • try 语句在抛出异常位置之前,且当前 catch 的名称与抛出的异常名称匹配:输出 catch 定义的输出内容,程序结束。
  • 否则,程序继续。
// 珍爱账号,请勿贺题
#include <bits/stdc++.h>
using namespace std;
#define int long long

int n,tp;
string s,ts;
stack<int>st;
// 1-try 2-catch 3-throw //
int func_type(){
    for(int i=0;i<s.length();i++){
        if(s.substr(i,3)=="try")return 1;
        if(s.substr(i,5)=="catch")return 2;
        if(s.substr(i,5)=="throw")return 3;
    }
    return -1;
}
string func_arg(bool is_last=0){
    string res="";
    // find 找元素,没找到返回 -1,找到返回位置,故判断是否找到时将返回值 +1 再转换为 bool 即可。
    int a=s.find("("),b=s.find(is_last?")":",");
    if(a+1&&b+1){
        for(int i=a+1;i<b;i++){
            if(s[i]!=' ')res+=s[i];
        }
    }
    return res;
}
void func_print(){
    int a=s.find("\""),b=s.rfind("\"");
    if(a+1&&b+1){
        for(int i=a+1;i<b;i++){
            cout<<s[i];
        }
        cout<<endl;
    }
}
void solve(){
    cin>>n;
    getline(cin,s); // 吃个换行先
    for(int i=1;i<=n;i++){
        getline(cin,s);
        int p=func_type();

        if(p==1){
            st.push(i);
        } else if(p==2) {
            int pp=st.top();
            st.pop();
            if(tp>pp && func_arg()==ts){
                func_print();
                return;
            }
        } else if(p==3) {
            ts = func_arg(1);
            tp = i;
        }
    }
    cout<<"Unhandled Exception"<<endl;
}

int32_t main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    solve();

    return 0;
}

评论