题解 | #S-expression#

S-expression

https://www.nowcoder.com/practice/7e6d2dd2e8774db3877f1fce2dd73834

#include <bits/stdc++.h>
using namespace std;

const unordered_set<string> errors = {"Division By Zero", "Type Mismatch", "Unbound Identifier"};
const unordered_set<string> binary = {"+", "-", "*", "/", "<", ">", "="};
map<string, string> value_map;

int find(const vector<string> &words, int x) {
    if (words[x] != "(") 
        return x;
    int rest = 1, poi = x + 1;
    while (poi < words.size()) {
        if (words[poi] == "(") 
            rest ++;
        if (words[poi] == ")")
            rest --;
        if (rest == 0)
            return poi;
        poi ++;
    }
    return poi;
}

string dfs(const vector<string> &words, int x, int y) {
    if (words[x] == "(")
        return dfs(words, x + 1, y - 1);
    if (binary.count(words[x])) {
        string le = "", ri = "";
        char op = words[x][0];
        int next = x + 1;
        if (words[x + 1] == "(") {
            next = find(words, x + 1);
        }
        le = dfs(words, x + 1, next);
        if (errors.count(le))
            return le;
        ri = dfs(words, next + 1, y);
        if (errors.count(ri)) 
            return ri;
        if (le == "true" || le == "false" || ri == "true" || ri == "false")
            return "Type Mismatch";
        int leVal = stoi(le), riVal = stoi(ri);
        switch (op) {
            case '+':
                return to_string(leVal + riVal);
            case '-':
                return to_string(leVal - riVal);
            case '*':
                return to_string(leVal * riVal);
            case '/':
                if (riVal == 0)
                    return "Division By Zero";
                return to_string(leVal / riVal);
            case '<':
                return leVal < riVal ? "true" : "false";
            case '>':
                return leVal > riVal ? "true" : "false";
            case '=':
                return leVal == riVal ? "true" : "false";
            default:
                return "Error";
        }
    }
    else if (words[x] == "if") {
        int next = find(words, x + 1);
        string res = dfs(words, x + 1, next);
        if (errors.count(res))
            return res;
        if (res != "true" && res != "false")
            return "Type Mismatch";
        string value;
        next ++;
        int last = find(words, next);
        if (res == "true") {
            return dfs(words, next, last);
        }
        else {
            next = last + 1;
            last = find(words, next);
            return dfs(words, next, last);
        }
    }
    else if (words[x] == "let") {
        int next = find(words, x + 1);
        string var = words[x + 2], value = dfs(words, x + 3, next - 1);
        if (errors.count(value))
            return value;
        value_map[var] = value;
        return dfs(words, next + 1, y);
    }
    else {
        if (words[x] == "true" || words[x] == "false")
            return words[x];
        if (words[x][0] >= 'a' && words[x][0] <= 'z' && !value_map.count(words[x]))
            return "Unbound Identifier";
        return value_map.count(words[x]) ? value_map[words[x]] : words[x];
    }
}

int main() {
    int n;
    cin >> n; cin.get();
    for (int test_case = 0; test_case < n; test_case++) {
        string s, word;
        getline(cin, s);
        stringstream ss(s);
        vector<string> words;
        while(ss >> word) {
            words.push_back(word);
        }
        cout << dfs(words, 0, word.size() - 1) << endl;
    } 
}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务