BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / python / #12920同步于 2016/3/25
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖

挑战:来做计算器

nuanyangyang
2016/3/25镜像同步30 回复
假设已经分割好了,输入是一个list,里面可能有数,也可能有运算符(用字符串表示)。运算符有加减乘除模和乘方,没有括号。请写一个函数求这个表达式的值。请优先考虑使代码长度最短而不是效率最高。不许使用eval和exec。 例子: def eval_expr(e): .... >>> eval_expr([1, '+', 1]) 2 >>> eval_expr([1, '-', 2, '*', 3, '**', 3, '/' 3]) # 先乘方,再乘除模,再加减 -17 >>> eval_expr([12, '%', 5]) 2 >>> eval_expr([2, '**', 3]) 8 >>> eval_expr([3, '-', 2, '-', 1]) # 同级运算,加减、乘除模都是从左到右 0 >>> eval_expr([3, '**', 3, '**', 3]) # 但乘方是右结合的 7625597484987
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
nuanyangyang机器人#1 · 2016/3/25
【 在 Dogless 的大作中提到: 】 : version 0 : [code=py] : def eval_expr(e): : ................... 尼玛,好暴力的e[::-1]
nuanyangyang机器人#2 · 2016/3/25
【 在 Dogless 的大作中提到: 】 : version 2 : [code=py] : def eval_expr(e): : ................... 试试这个输入:[3, "-", 2, "+", 1]
nuanyangyang机器人#3 · 2016/3/25
【 在 Dogless 的大作中提到: 】 : : 为什么错啦? 你猜
asif12机器人#4 · 2016/3/25
占坑,今天复试刚考完编译原理,明天机试完再碰python
glazard机器人#5 · 2016/3/25
def eval_expr(e): return reduce(lambda s, x: s[:-1] + [s[-1] + x[1] if x[0] == '+' else s[-1] - x[1]] if x[0] == '+' or x[0] == '-' else s + x, *(lambda e2: (([e2[i], e2[i+1]] for i in xrange(1, len(e2), 2)), [e2[0]]))(reduce(lambda s, x: s[:-1] + [s[-1] * x[1] if x[0] == '*' else s[-1] / x[1] if x[0] == '/' else s[-1] % x[1]] if x[0] == '*' or x[0] == '/' or x[0] == '%' else s + x, *(lambda e1: (([e1[i], e1[i+1]] for i in xrange(1, len(e1), 2)), [e1[0]]))(reduce(lambda s, x: s[:-1] + [x[1] ** s[-1]] if x[0] == '**' else s + x, ([e[i], e[i-1]] for i in xrange(len(e)-2, -1, -2)), [e[-1]])[::-1]))))[0] 除了压进了一行以外好像一点也不短……又拆开写了一遍 OPS = [('+', '-'), ('*', '/', '%'), ('**')] def exec_op(op, x, y): if op == '**': return x ** y if op == '*': return x * y if op == '/': return x / y if op == '%': return x % y if op == '+': return x + y if op == '-': return x - y def eval_once(e, lvl): if lvl == 2: e = e[::-1] s = [e[0]] for i in xrange(1, len(e), 2): if e[i] in OPS[lvl]: s[-1] = exec_op(e[i], s[-1], e[i+1]) else: s = s + [e[i], e[i+1]] return s[::-1] if lvl == 2 else s def eval_expr(e): return eval_once(eval_once(eval_once(e, 2), 1), 0)[0] 另外一个不说人话版 def exec_op(op, x, y): if op == '**': return x ** y if op == '*': return x * y if op == '/': return x / y if op == '%': return x % y if op == '+': return x + y if op == '-': return x - y def split(lst, seps): r = [[]] for i in lst: if i in seps: r += [i, []] else: r[-1].append(i) return r def chunk_with_plus(a): return zip(['+'] + a[1::2], a[0::2]) def eval_expr(e): return reduce(lambda s0, x0: exec_op(x0[0], s0, reduce(lambda s1, x1: exec_op(x1[0], s1, reduce(lambda s2, x2: x2 ** s2, x1[1][-3::-2], x1[1][-1])), chunk_with_plus(x0[1]), 0)), chunk_with_plus([split(l1, set(('*', '/', '%'))) if isinstance(l1, list) else l1 for l1 in (split(e, set(('+', '-'))))]), 0) 把这一版展开 def exec_op(op, x, y): if op == '**': return x ** y if op == '*': return x * y if op == '/': return x / y if op == '%': return x % y if op == '+': return x + y if op == '-': return x - y def split(lst, seps): r = [[]] for i in lst: if i in seps: r += [i, []] else: r[-1].append(i) return r def eval_lvl2(e): return reduce(lambda s, x: x ** s, e[-3::-2], e[-1]) def eval_lvl1(e): e = split(e, set(('*', '/', '%'))) return reduce(lambda s, x: exec_op(x[0], s, eval_lvl2(x[1])), zip(e[1::2], e[2::2]), eval_lvl2(e[0])) def eval_expr(e): e = split(e, set(('+', '-'))) return reduce(lambda s, x: exec_op(x[0], s, eval_lvl1(x[1])), zip(e[1::2], e[2::2]), eval_lvl1(e[0]))
caicai617机器人#6 · 2016/3/25
我记得计算器是leetcode上最难一题?
nuanyangyang机器人#7 · 2016/3/25
【 在 glazard 的大作中提到: 】 : ................... >>> eval_expr([2,"**",3]) 9
glazard机器人#8 · 2016/3/25
展开的时候把两个参数弄倒了…… OPS = [('+', '-'), ('*', '/', '%'), ('**')] def exec_op(op, x, y): if op == '**': return x ** y if op == '*': return x * y if op == '/': return x / y if op == '%': return x % y if op == '+': return x + y if op == '-': return x - y def eval_once(e, lvl): if lvl == 2: e = e[::-1] s = [e[0]] for i in xrange(1, len(e), 2): if e[i] in OPS[lvl]: if lvl == 2: s[-1] = exec_op(e[i], e[i+1], s[-1]) else: s[-1] = exec_op(e[i], s[-1], e[i+1]) else: s = s + [e[i], e[i+1]] return s[::-1] if lvl == 2 else s def eval_expr(e): return eval_once(eval_once(eval_once(e, 2), 1), 0)[0] print(eval_expr([2,"**",3])) 另外补了一个比较正常的版本 OPS = (set(('+', '-')), set(('*', '/', '%')), set(('**',))) def exec_op(op, x, y): if op == '**': return x ** y if op == '*': return x * y if op == '/': return x / y if op == '%': return x % y if op == '+': return x + y if op == '-': return x - y def eval_lvl(e, lvl, right=False): if lvl == 3: return e[0] for i in xrange(1, len(e) - 1, 2) if right else xrange(len(e) - 2, 0, -2): op = e[i] if op in OPS[lvl]: if right: return exec_op(op, eval_lvl(e[:i], lvl+1, lvl==1), eval_lvl(e[i+1:], lvl, right)) else: return exec_op(op, eval_lvl(e[:i], lvl, right), eval_lvl(e[i+1:], lvl+1, lvl==1)) return eval_lvl(e, lvl+1, lvl==1) def eval_expr(e): return eval_lvl(e, 0, False) 【 在 nuanyangyang 的大作中提到: 】 : : >>> eval_expr([2,"**",3]) : 9 : ...................
json123机器人#9 · 2016/3/25
等回去写个swift版本的