[Swift]LeetCode770. 基本计算器 IV | Basic Calculator IV
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https://www.cnblogs.com/strengthen/p/10536324.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Given an expression
such as expression = "e + 8 - a + 5"
and an evaluation map such as {"e": 1}
(given in terms of evalvars = ["e"]
and evalints = [1]
), return a list of tokens representing the simplified expression, such as ["-1*a","14"]
- An expression alternates chunks and symbols, with a space separating each chunk and symbol.
- A chunk is either an expression in parentheses, a variable, or a non-negative integer.
- A variable is a string of lowercase letters (not including digits.) Note that variables can be multiple letters, and note that variables never have a leading coefficient or unary operator like
"2x"
or"-x"
.
Expressions are evaluated in the usual order: brackets first, then multiplication, then addition and subtraction. For example, expression = "1 + 2 * 3"
has an answer of ["7"]
.
The format of the output is as follows:
- For each term of free variables with non-zero coefficient, we write the free variables within a term in sorted order lexicographically. For example, we would never write a term like
"b*a*c"
, only"a*b*c"
. - Terms have degree equal to the number of free variables being multiplied, counting multiplicity. (For example,
"a*a*b*c"
has degree 4.) We write the largest degree terms of our answer first, breaking ties by lexicographic order ignoring the leading coefficient of the term. - The leading coefficient of the term is placed directly to the left with an asterisk separating it from the variables (if they exist.) A leading coefficient of 1 is still printed.
- An example of a well formatted answer is
["-2*a*a*a", "3*a*a*b", "3*b*b", "4*a", "5*c", "-6"]
- Terms (including constant terms) with coefficient 0 are not included. For example, an expression of "0" has an output of [].
Examples:
Input: expression = "e + 8 - a + 5", evalvars = ["e"], evalints = [1] Output: ["-1*a","14"] Input: expression = "e - 8 + temperature - pressure", evalvars = ["e", "temperature"], evalints = [1, 12] Output: ["-1*pressure","5"] Input: expression = "(e + 8) * (e - 8)", evalvars = [], evalints = [] Output: ["1*e*e","-64"] Input: expression = "7 - 7", evalvars = [], evalints = [] Output: [] Input: expression = "a * b * c + b * a * c * 4", evalvars = [], evalints = [] Output: ["5*a*b*c"] Input: expression = "((a - b) * (b - c) + (c - a)) * ((a - b) + (b - c) * (c - a))", evalvars = [], evalints = [] Output: ["-1*a*a*b*b","2*a*a*b*c","-1*a*a*c*c","1*a*b*b*b","-1*a*b*b*c","-1*a*b*c*c","1*a*c*c*c","-1*b*b*b*c","2*b*b*c*c","-1*b*c*c*c","2*a*a*b","-2*a*a*c","-2*a*b*b","2*a*c*c","1*b*b*b","-1*b*b*c","1*b*c*c","-1*c*c*c","-1*a*a","1*a*b","1*a*c","-1*b*c"]
Note:
expression
will have length in range[1, 250]
.evalvars, evalints
will have equal lengths in range[0, 100]
.
给定一个表达式 expression
如 expression = "e + 8 - a + 5"
和一个求值映射,如 {"e": 1}
(给定的形式为 evalvars = ["e"]
和 evalints = [1]
),返回表示简化表达式的标记列表,例如 ["-1*a","14"]
- 表达式交替使用块和符号,每个块和符号之间有一个空格。
- 块要么是括号中的表达式,要么是变量,要么是非负整数。
- 块是括号中的表达式,变量或非负整数。
- 变量是一个由小写字母组成的字符串(不包括数字)。请注意,变量可以是多个字母,并注意变量从不具有像
"2x"
或"-x"
这样的前导系数或一元运算符 。
表达式按通常顺序进行求值:先是括号,然后求乘法,再计算加法和减法。例如,expression = "1 + 2 * 3"
的答案是 ["7"]
。
输出格式如下:
- 对于系数非零的每个自变量项,我们按字典排序的顺序将自变量写在一个项中。例如,我们永远不会写像
“b*a*c”
这样的项,只写“a*b*c”
。 - 项的次数等于被乘的自变量的数目,并计算重复项。(例如,
"a*a*b*c"
的次数为 4。)。我们先写出答案的最大次数项,用字典顺序打破关系,此时忽略词的前导系数。 - 项的前导系数直接放在左边,用星号将它与变量分隔开(如果存在的话)。前导系数 1 仍然要打印出来。
- 格式良好的一个示例答案是
["-2*a*a*a", "3*a*a*b", "3*b*b", "4*a", "5*c", "-6"]
。 - 系数为 0 的项(包括常数项)不包括在内。例如,“0” 的表达式输出为 []。
示例:
输入:expression = "e + 8 - a + 5", evalvars = ["e"], evalints = [1] 输出:["-1*a","14"] 输入:expression = "e - 8 + temperature - pressure", evalvars = ["e", "temperature"], evalints = [1, 12] 输出:["-1*pressure","5"] 输入:expression = "(e + 8) * (e - 8)", evalvars = [], evalints = [] 输出:["1*e*e","-64"] 输入:expression = "7 - 7", evalvars = [], evalints = [] 输出:[] 输入:expression = "a * b * c + b * a * c * 4", evalvars = [], evalints = [] 输出:["5*a*b*c"] 输入:expression = "((a - b) * (b - c) + (c - a)) * ((a - b) + (b - c) * (c - a))", evalvars = [], evalints = [] 输出:["-1*a*a*b*b","2*a*a*b*c","-1*a*a*c*c","1*a*b*b*b","-1*a*b*b*c","-1*a*b*c*c","1*a*c*c*c","-1*b*b*b*c","2*b*b*c*c","-1*b*c*c*c","2*a*a*b","-2*a*a*c","-2*a*b*b","2*a*c*c","1*b*b*b","-1*b*b*c","1*b*c*c","-1*c*c*c","-1*a*a","1*a*b","1*a*c","-1*b*c"]
提示:
expression
的长度在[1, 250]
范围内。evalvars, evalints
在范围[0, 100]
内,且长度相同。
[]
[]
[]
[]
1 class Solution { 2 //evaluation map 3 static var map:[String:Int] = [String:Int]() 4 5 func basicCalculatorIV(_ expression: String, _ evalvars: [String], _ evalints: [Int]) -> [String] { 6 for i in 0..<evalvars.count 7 { 8 Solution.map[evalvars[i]] = evalints[i] 9 } 10 var i:Int = 0 11 var l:Int = expression.count 12 var stack:[Expression] = [Expression]() 13 var priStack:[Int] = [Int]() 14 var zero:Expression = Expression(0) 15 stack.append(zero) 16 priStack.append(0) 17 var pri:Int = 0 18 19 while (i < l) 20 { 21 var ch:Character = expression[i] 22 if ch.isDigit() 23 { 24 var num:Int = 0 25 while (i < l && expression[i].isDigit()) 26 { 27 num = num * 10 + (expression[i].ascii - 48) 28 i += 1 29 } 30 stack.append(Expression(num)) 31 continue 32 } 33 if ch.isLetter() 34 { 35 var s:String = String() 36 while (i < l && expression[i].isLetter()) 37 { 38 s.append(expression[i]) 39 i += 1 40 } 41 stack.append(Expression(s)) 42 continue 43 } 44 if ch == "(" {pri += 2} 45 if ch == ")" {pri -= 2} 46 if ch == "+" || ch == "-" || ch == "*" 47 { 48 var nowPri:Int = pri 49 if ch == "*" {nowPri += 1} 50 while (!priStack.isEmpty && nowPri <= priStack.last!) 51 { 52 var now:Expression = stack.removeLast() 53 var last:Expression = stack.removeLast() 54 priStack.removeLast() 55 stack.append(last.cal(now)) 56 } 57 stack[stack.count - 1].oper = ch 58 priStack.append(nowPri) 59 } 60 i += 1 61 } 62 63 while (stack.count > 1) 64 { 65 var now:Expression = stack.removeLast() 66 var last:Expression = stack.removeLast() 67 stack.append(last.cal(now)) 68 } 69 70 return stack.last!.toList() 71 } 72 } 73 74 class Term 75 { 76 //the parameter of this term 77 var para:Int = 1 78 //each factor (e.a. a*b*b*c->{a,b,b,c}) 79 var arr:[String] = [String]() 80 81 init(_ x:Int) 82 { 83 self.para = x 84 } 85 86 init(_ s:String) 87 { 88 if Solution.map[s] == nil 89 { 90 arr.append(s) 91 } 92 else 93 { 94 para = Solution.map[s]! 95 } 96 } 97 98 init(_ that:Term) 99 { 100 self.para = that.para 101 self.arr = that.arr 102 } 103 104 func toString() -> String 105 { 106 if para == 0 {return String()} 107 var ans:String = String() 108 for s in arr 109 { 110 ans += ("*" + s) 111 } 112 return String(para) + ans 113 } 114 115 func equals(_ that:Term) -> Bool 116 { 117 if self.arr.count != that.arr.count 118 { 119 return false 120 } 121 for i in 0..<self.arr.count 122 { 123 if self.arr[i] != that.arr[i] 124 { 125 return false 126 } 127 } 128 return true 129 } 130 131 func compareTo(_ that:Term) -> Int 132 { 133 if self.arr.count > that.arr.count {return -1} 134 if self.arr.count < that.arr.count {return 1} 135 for i in 0..<self.arr.count 136 { 137 var x:Int = 0 138 if self.arr[i] > that.arr[i] 139 { 140 x = 1 141 } 142 else if self.arr[i] < that.arr[i] 143 { 144 x = -1 145 } 146 else 147 { 148 x = 0 149 } 150 if x != 0 {return x} 151 } 152 return 0 153 } 154 155 func times(_ that:Term) -> Term 156 { 157 var pro = Term(self.para * that.para) 158 for s in self.arr 159 { 160 pro.arr.append(String(s)) 161 } 162 for s in that.arr 163 { 164 pro.arr.append(String(s)) 165 } 166 pro.arr = pro.arr.sorted(by:>) 167 return pro 168 } 169 } 170 171 class Expression 172 { 173 //Term List 174 var list:[Term] = [Term]() 175 var oper:Character = "+" 176 177 init(_ x:Int) 178 { 179 self.list.append(Term(x)) 180 } 181 182 init(_ s:String) 183 { 184 self.list.append(Term(s)) 185 } 186 187 init(_ l:[Term]) 188 { 189 self.list = l 190 } 191 192 func times(_ that:Expression) -> Expression 193 { 194 var c:[Term] = [Term]() 195 for t1 in self.list 196 { 197 for t2 in that.list 198 { 199 c.append(t1.times(t2)) 200 } 201 } 202 c = combine(c) 203 return Expression(c) 204 } 205 206 func plus(_ that:Expression,_ sgn:Int) -> Expression 207 { 208 var c:[Term] = [Term]() 209 for t in self.list 210 { 211 c.append(Term(t)) 212 } 213 for t in that.list 214 { 215 var t2:Term = Term(t) 216 t2.para = t2.para * sgn 217 c.append(t2) 218 } 219 c = combine(c) 220 return Expression(c) 221 } 222 223 func cal(_ that:Expression) -> Expression 224 { 225 if oper == "+" 226 { 227 return plus(that,1) 228 } 229 if oper == "-" 230 { 231 return plus(that,-1) 232 } 233 return times(that) 234 } 235 236 func toList() -> [String] 237 { 238 var ans:[String] = [String]() 239 for t in list 240 { 241 var s:String = t.toString() 242 if s.count > 0 {ans.append(s)} 243 } 244 return ans 245 } 246 247 func combine(_ a:[Term]) -> [Term] 248 { 249 var a = a 250 a.sort(by:{(t1:Term,t2:Term) -> Bool in 251 return t1.compareTo(t2) < 0}) 252 var c:[Term] = [Term]() 253 for t in a 254 { 255 if c.count != 0 && t.equals(c.last!) 256 { 257 c[c.count - 1].para += t.para 258 } 259 else 260 { 261 c.append(Term(t)); 262 } 263 } 264 return c 265 } 266 } 267 268 //String扩展 269 extension String { 270 //subscript函数可以检索数组中的值 271 //直接按照索引方式截取指定索引的字符 272 subscript (_ i: Int) -> Character { 273 //读取字符 274 get {return self[index(startIndex, offsetBy: i)]} 275 } 276 } 277 278 //Character扩展 279 extension Character 280 { 281 //Character转ASCII整数值(定义小写为整数值) 282 var ascii: Int { 283 get { 284 return Int(self.unicodeScalars.first?.value ?? 0) 285 } 286 } 287 288 func isDigit() -> Bool 289 { 290 if self.ascii > 47 && self.ascii < 58 291 { 292 return true 293 } 294 return false 295 } 296 297 func isLetter() -> Bool 298 { 299 if (self.ascii > 64 && self.ascii < 91) || self.ascii > 96 && self.ascii < 123 300 { 301 return true 302 } 303 return false 304 } 305 }