记忆:用硬币找零
Posted
技术标签:
【中文标题】记忆:用硬币找零【英文标题】:Memoization: Making change with coins 【发布时间】:2015-07-03 22:00:42 【问题描述】:我正在用 Python 解决经典的用硬币找零问题。这是我的实现。
def memo(fn):
def helper(*args): # here, * indicate the fn take arbitrary number of argumetns
d =
if args in d:
return d[args] # args is a tuple, immutable, hashable
else:
res = fn(*args) # here * expand a tuple as arguments
d[args] = res
return res
return helper
@memo
def change(options, n):
if n < 0 or options ==():
return 0
elif n == 0:
return 1
else:
return change(options, n- options[0]) + change(options[1:], n)
事实证明,memoized 版本比原始版本还要慢!为什么?我的实现出了什么问题?
这是没有记忆的:
In [172]: %timeit change((50, 25, 10, 5, 1), 100)
100 loops, best of 3: 7.12 ms per loop
这是有记忆的:
In [170]: %timeit change((50, 25, 10, 5, 1), 100)
10 loops, best of 3: 21.2 ms per loop
【问题讨论】:
您正在创建一个新的 "cache" 字典每次调用装饰函数时 这种技术的术语是“记忆”,而不是“记忆”。不要相信你的拼写检查器。 感谢指正。我一直认为是背诵orz。现在我知道人脑有多么强大可以自动填充幻想 XD 【参考方案1】:在您当前的代码中:
def memo(fn):
def helper(*args):
d =
您创建一个新的“缓存”字典d
每次调用装饰函数时。难怪它变慢了!最小的修复是:
def memo(fn):
d =
def helper(*args):
但它通常会更整洁。我用:
def memo(func):
def wrapper(*args):
if args not in wrapper.cache:
wrapper.cache[args] = func(*args)
return wrapper.cache[args]
wrapper.cache =
return wrapper
这使得访问修饰函数的cache
进行错误修复等变得更加容易。
【讨论】:
哇,所以您将字典作为字段分配给包装函数对象。这有点干净。谢谢!!以上是关于记忆:用硬币找零的主要内容,如果未能解决你的问题,请参考以下文章