Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 需要帮助了解如何实施备忘录化吗_Python_Algorithm_Recursion_Memoization - Fatal编程技术网

Python 需要帮助了解如何实施备忘录化吗

Python 需要帮助了解如何实施备忘录化吗,python,algorithm,recursion,memoization,Python,Algorithm,Recursion,Memoization,我正在努力完成我的第一个实现备忘录的练习,但我无法思考如何解决这个问题: 我有一个函数,它将输入文本包装到指定的行长度,然后打印结果 def wrap(input, lineSpaces): if len(input) <= lineSpaces: return input temp = input.rfind(" ", 0, lineSpaces - 1) if temp == -1: return input else:

我正在努力完成我的第一个实现备忘录的练习,但我无法思考如何解决这个问题:

我有一个函数,它将输入文本包装到指定的行长度,然后打印结果

def wrap(input, lineSpaces):
    if len(input) <= lineSpaces:
        return input
    temp = input.rfind(" ", 0, lineSpaces - 1)
    if temp == -1:
        return input
    else:
        return input[:temp+1]+'\n'+wrap(input[temp+1:], lineSpaces)

# I/O
list = []
M = int(raw_input())
for i in xrange(0, M):
    lineSpaces = int(raw_input())
    input = raw_input()
    list.append(wrap(input, lineSpaces))

for i in list:
    print i+"\n"
我得到:

Lorem ipsum dolor 
sit amet, 
consectetuer 
adipiscing elit. ALorem ipsum dolor sit amet,

Lorem ipsum dolor sit amet, 
consectetuer adipiscing 
elit. Aenean commodo ligula 
eget dolor. Aenean massa. CuLorem ipsum dolor sit amet,

Lorem ipsum dolor sit amet,Lorem ipsum dolor sit amet,

这显然是错误的。看起来我的“记忆化”版本唯一要做的就是将最终输出附加到其他输出。所以,我认为我对如何实际实现这个函数的记忆的理解是完全错误的。有人能给我指出正确的方向吗?

记忆是你在实现一个功能时做的事情,而不是在使用它时。当您生成输出时,您将记录此调用的输入与您生成的输出相对应。当你接到一个电话时,你会检查你是否已经为你收到的输入保存了输出,如果已经保存了,你就使用存储的输出。看起来是这样的:

_memodict = {}
def memoized_function(input):
    try:
        return _memodict[input]
    except KeyError:
        # do what you would have normally done
        _memodict[input] = output
        return output
import functools
def memoize(function):
    _memodict = {}

    # This decorator just makes the new function look a bit nicer
    @functools.wraps(function)
    def wrapped(*args):
        try:
            return _memodict[args]
        except KeyError:
            output = _memodict[args] = function(*args)
            return output
    return wrapped

@memoize
def function(input):
    # Exactly what you would have written normally
或者像这样:

_memodict = {}
def memoized_function(input):
    try:
        return _memodict[input]
    except KeyError:
        # do what you would have normally done
        _memodict[input] = output
        return output
import functools
def memoize(function):
    _memodict = {}

    # This decorator just makes the new function look a bit nicer
    @functools.wraps(function)
    def wrapped(*args):
        try:
            return _memodict[args]
        except KeyError:
            output = _memodict[args] = function(*args)
            return output
    return wrapped

@memoize
def function(input):
    # Exactly what you would have written normally

顺便说一句,这个函数并不特别适合于记忆。对于反复进行相同的递归调用的情况,memonization尤其有用。在那里,它可以将指数时间算法转换为线性时间。在这里,递归无法利用备忘录,我不知道您是否可能反复尝试对同一文本进行word包装。(也许你是。我想这取决于你的申请。)谢谢你的回复,这更有意义。我想我现在有了一些东西--除了确认我有预期的输出、打印语句调试等之外,你知道有什么方法可以确保备忘录功能实际工作吗?@user3681725:确保递归调用也能命中备忘录,通过使用先前递归调用中可能出现的输入之一调用已记忆的函数,并验证该函数是否采用快速路径。如果您编写了一个备忘录装饰器,您可以尝试使用朴素的递归斐波那契实现(即
fib(n-1)+fib(n-2)
)。记住,该实现应该能够处理像
fib(200)
这样的输入。如果备忘录不起作用,像这样的输入永远不会结束。好吧,好主意。看起来它在
fib(124)
及以下的所有对象上都能很快地工作,但是任何超过该值的对象都会导致
运行时错误:超过最大递归深度。你认为我的原始函数需要修复吗?@user3681725:我不确定额外的堆栈帧来自哪里。这可能只是您的实现和我的实现之间的良性差异,也可能是一个问题。我倾向于“没问题”,太好了。谢谢你的帮助!