★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-hxyalguf-ev.html
➤若是连接不是山青咏芝的博客园地址,则多是爬取做者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持做者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
You are given a string expression
representing a Lisp-like expression to return the integer value of.git
The syntax for these expressions is given as follows.github
(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
.Evaluation Examples:express
Input: (add 1 2) Output: 3 Input: (mult 3 (add 2 3)) Output: 15 Input: (let x 2 (mult x 5)) Output: 10 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. Input: (let x 3 x 2 x) Output: 2 Explanation: Assignment in let statements is processed sequentially. Input: (let x 1 y 2 x (add x y) (add x y)) Output: 5 Explanation: The first (add x y) evaluates as 3, and is assigned to x. The second (add x y) evaluates as 3+2 = 5. Input: (let x 2 (add (let x 3 (let x 4 x)) x)) Output: 6 Explanation: Even though (let x 4 x) has a deeper scope, it is outside the context of the final x in the add-expression. That final x will equal 2. Input: (let a1 3 b2 (add a1 1) b2) Output 4 Explanation: Variable names can contain digits after the first character.
Note:数组
expression
is well formatted: There are no leading or trailing spaces, there is only a single space separating different components of the string, and no space between adjacent parentheses. The expression is guaranteed to be legal and evaluate to an integer.expression
is at most 2000. (It is also non-empty, as that would not be a legal expression.)给定一个相似 Lisp 语句的表达式 expression
,求出其计算结果。微信
表达式语法以下所示:ide
(let v1 e1 v2 e2 ... vn en expr)
, 其中 let
语法老是以字符串 "let"
来表示,接下来会跟随一个或多个交替变量或表达式,也就是说,第一个变量 v1
被分配为表达式 e1
的值,第二个变量 v2
被分配为表达式 e2
的值,以此类推;最终 let 语法的值为 expr
表达式的值。(add e1 e2)
,其中 add
语法老是以字符串 "add"
来表示,该语法老是有两个表达式e1
、e2
, 该语法的最终结果是 e1
表达式的值与 e2
表达式的值之和。(mult e1 e2)
,其中 mult
语法老是以字符串"mult"
表示, 该语法老是有两个表达式 e1
、e2
,该语法的最终结果是 e1
表达式的值与 e2
表达式的值之积。示例:函数
输入: (add 1 2) 输出: 3 输入: (mult 3 (add 2 3)) 输出: 15 输入: (let x 2 (mult x 5)) 输出: 10 输入: (let x 2 (mult x (let x 3 y 4 (add x y)))) 输出: 14 解释: 表达式 (add x y), 在获取 x 值时, 咱们应当由最内层依次向外计算, 首先遇到了 x=3, 因此此处的 x 值是 3. 输入: (let x 3 x 2 x) 输出: 2 解释: let 语句中的赋值运算按顺序处理便可 输入: (let x 1 y 2 x (add x y) (add x y)) 输出: 5 解释: 第一个 (add x y) 计算结果是 3,而且将此值赋给了 x 。 第二个 (add x y) 计算结果就是 3+2 = 5 。 输入: (let x 2 (add (let x 3 (let x 4 x)) x)) 输出: 6 解释: (let x 4 x) 中的 x 的做用范围仅在()以内。因此最终作加法操做时,x 的值是 2 。 输入: (let a1 3 b2 (add a1 1) b2) 输出: 4 解释: 变量命名时能够在第一个小写字母后跟随数字.
注意:测试
expression
表达式都是格式化后的:表达式先后没有多余的空格,表达式的不一样部分(关键字、变量、表达式)之间仅使用一个空格分割,而且在相邻括号之间也没有空格。咱们给定的表达式均为合法的且最终结果为整数。1 class Solution { 2 func evaluate(_ expression: String) -> Int { 3 var m:[String:Int] = [String:Int]() 4 return helper(expression, m) 5 } 6 7 func helper(_ str:String,_ m:[String:Int]) -> Int 8 { 9 var arr:[Character] = Array(str) 10 var m = m 11 if arr[0] == "-" || (arr[0] >= "0" && arr[0] <= "9") 12 { 13 return Int(str) ?? 0 14 } 15 else if arr[0] != "(" 16 { 17 return m[str,default:0] 18 } 19 var s:String = str.subString(1, str.count - 2) 20 var cur:Int = 0 21 var cmd:String = parse(&s, &cur) 22 if cmd == "let" 23 { 24 while (true) { 25 var str2 = parse(&s, &cur) 26 if cur > s.count 27 { 28 return helper(str2, m) 29 } 30 var t:String = parse(&s, &cur) 31 m[str2] = helper(t, m) 32 } 33 } 34 else if cmd == "add" 35 { 36 return helper(parse(&s, &cur), m) + helper(parse(&s, &cur), m) 37 } 38 else if cmd == "mult" 39 { 40 return helper(parse(&s, &cur), m) * helper(parse(&s, &cur), m) 41 } 42 return 0 43 } 44 45 func parse(_ s:inout String,_ cur:inout Int) -> String 46 { 47 var end:Int = cur + 1 48 var t:Int = cur 49 var cnt:Int = 1 50 if s[cur] == "(" 51 { 52 while (cnt != 0) 53 { 54 if s[end] == "(" 55 { 56 cnt += 1 57 } 58 else if s[end] == ")" 59 { 60 cnt -= 1 61 } 62 end += 1 63 } 64 65 } 66 else 67 { 68 while (end < s.count && s[end] != " ") 69 { 70 end += 1 71 } 72 73 } 74 cur = end + 1 75 return s.subString(t, end - t) 76 } 77 } 78 79 extension String { 80 //subscript函数能够检索数组中的值 81 //直接按照索引方式截取指定索引的字符 82 subscript (_ i: Int) -> Character { 83 //读取字符 84 get {return self[index(startIndex, offsetBy: i)]} 85 } 86 87 // 截取字符串:指定索引和字符数 88 // - begin: 开始截取处索引 89 // - count: 截取的字符数量 90 func subString(_ begin:Int,_ count:Int) -> String { 91 let start = self.index(self.startIndex, offsetBy: max(0, begin)) 92 let end = self.index(self.startIndex, offsetBy: min(self.count, begin + count)) 93 return String(self[start..<end]) 94 } 95 }