This page explains Java solution to problem Parse Lisp Expression
using String
data structure.
You are given a string expression
representing a Lisp-like expression to return the integer value of.
The syntax for these expressions is given as follows.
(let v1 e1 v2 e2 ... vn en expr)
, where let is always the string "let", then there are 1 or more pairs of alternating variables and expressions, meaning that the first variable v1 is assigned the value of the expression e1, the second variable v2 is assigned the value of the expression e2, and so on sequentially; and then the value of this let-expression is the value of the expression expr.(add e1 e2)
where add is always the string "add"
, there are always two expressions e1
, e2
, and this expression evaluates to the addition of the evaluation of e1
and the evaluation of e2
.(mult e1 e2)
where mult is always the string "mult"
, there are always two expressions e1
, e2
, and this expression evaluates to the multiplication of the evaluation of e1
and the evaluation of e2
."add"
, "let"
, or "mult"
are protected and will never be used as variable names.Example 2:Input: (add 1 2)
Output: 3
Example 3:Input: (mult 3 (add 2 3))
Output: 15
Input: (let x 2 (mult x (let x 3 y 4 (add x y))))
Output: 14
Explanation:
In the expression (add x y), when checking for the value of the variable x,
we check from the innermost scope to the outermost in the context of the variable we are trying to evaluate.
Since x = 3 is found first, the value of x is 3.
package com.vc.hard;
import java.util.*;
class ParseLispExpression {
public int evaluate(String expression) {
HashMap<String, Integer> variables = new HashMap<>();
return solve(expression, variables);
}
private int solve(String expression, HashMap<String, Integer> variables) {
if(isNumber(expression)) return Integer.parseInt(expression);
else if(isVariable(expression)) return variables.get(expression);
List<String> list = parse(expression);
if(list.get(0).equals("add")) {
return solve(list.get(1), variables) + solve(list.get(2), variables);
}
else if(list.get(0).equals("mult")) {
return solve(list.get(1), variables) * solve(list.get(2), variables);
}
else {
HashMap<String, Integer> subVariables = new HashMap<>(variables);
for(int i = 1; i < list.size() - 2; i += 2) {
String variable = list.get(i);
int value = solve(list.get(i + 1), subVariables);
subVariables.put(variable, value);
}
return solve(list.get(list.size() - 1), subVariables);
}
}
private List<String> parse(String expression) {
int n = expression.length();
StringBuilder str = new StringBuilder();
List<String> list = new ArrayList<>();
int countParen = 0;
for(int i = 1; i < expression.length() - 1; i++) {
char ch = expression.charAt(i);
if(ch == ')') {
str.append(")");
countParen--;
}
else if(ch == '(') {
str.append("(");
countParen++;
}
else if(ch == ' ' && countParen == 0) {
list.add(str.toString());
str.setLength(0);
}
else str.append(ch);
}
if(str.length() > 0) list.add(str.toString());
return list;
}
private boolean isNumber(String expression) {
char ch = expression.charAt(0);
return (ch >= '0' && ch <= '9') || ch == '-';
}
private boolean isVariable(String expression) {
char ch = expression.charAt(0);
return ch >= 'a' && ch <= 'z';
}
}
O(N2) Where
N is length of expression
O(N2) Where
N is length of expression