码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 736. Parse Lisp Expression

时间:2019-07-14 14:53:00      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:lse   const   bre   nbsp   lis   let   return   括号   int   

表达式相关的题目,由于会出现各种嵌套,通常用递归来做。

递归来做主要由两种,如 op e1 e2

1. 通过括号或者空格找到 e1, e2 的范围,递归求解 e1, e2。

2. 直接递归求解,在递归内找 e 的范围。

 

由于本题比较复杂,很难直接把嵌套的表达式找出来,因此采用第二种方法,在递归中处理嵌套表达式,同时处理括号等边界情况。而且由于scope的存在,本题需要一个栈来记录 variable 的值,进入递归的时候压栈,退出的时候出栈。

let非常繁琐,ei 和 expr 都可以是表达式,需要递归求解,而 vi 一定只是个字符串,用 getToken 得到即可。

class Solution {
public:
    deque<unordered_map<string,int>> scopes;
    
    int evaluate(string expression) {
        int pos=0;
        return eval(expression, pos);
    }
    
    int eval(const string &s, int &pos){
        scopes.push_front(unordered_map<string,int>());
        int value=0; //return val of current expr
        if (s[pos]==() ++pos;
        
        string token=getToken(s,pos);
        //cout << token << endl;
        
        if (token=="add"){ // expecting " e1 e2)"
            int e1=eval(s,++pos); //skip ‘ ‘
            int e2=eval(s,++pos);
            value = e1 + e2;
        }else if (token=="mult"){
            int e1=eval(s,++pos); //skip ‘ ‘
            int e2=eval(s,++pos);
            value = e1 * e2;
        }else if (token=="let"){
            // expecting " let v1 e1 v2 e2 ... vn en expr) ...."
            while (pos<s.size()){
                // since ei will be dealt with vi, here can only be vi or expr
                if (s[++pos]==(){ // if expr is an expression (...)
                    value = eval(s,++pos);
                    break;
                }
                 
                // var can be vi or expr (expr of variable or int)
                string var=getToken(s,pos);
                
                if (s[pos]==)){ // var is expr
                    if (isalpha(var[0])) // expr is variable
                        value = getValue(var);
                    else // expr is int
                        value = stoi(var);
                    break;
                }
                
                // var is vi, now read next token to be vi
                scopes.front()[var] = eval(s,++pos);
                //cout << var << "<-" << scopes.front()[var] <<endl;
            }
        }else if (isalpha(token[0])){ // variable
            value = getValue(token);
        }else{ // number
            value = stoi(token);
        }
        
        if (s[pos]==)) ++pos;
        scopes.pop_front();
        return value;
    }

    string getToken(const string &s, int &pos){
        string token="";
        while (pos<s.size()){
            if (s[pos]==) || s[pos]== ) break;
            token += s[pos++];
        }
        return token;
    }
    
    int getValue(string var){
        for (auto scope:scopes){
            if (scope.count(var)) return scope[var];
        }
        return 0;
    }
};

 

LeetCode 736. Parse Lisp Expression

标签:lse   const   bre   nbsp   lis   let   return   括号   int   

原文地址:https://www.cnblogs.com/hankunyan/p/11184109.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!