【问题标题】:Varying recursive function at given depth在给定深度改变递归函数
【发布时间】:2018-10-22 14:27:50
【问题描述】:

我有一个使用 python turtle 模块绘制分形的递归函数:

def fract(t, order, size):
    if order == 0:
        t.forward(size)

    else:
        for angle in (60, -120, 60, 0):
            fract(t, order - 1, size / 3)
            t.left(angle)

我有另一个函数调用第一个函数并修改最后一个角度,以便分形构建一个圆

def circle(t, order, size):
    for i in range(order):
        fract(t, 2, size)
        t.right(360 / order)

circle(t, 4, 300)

虽然这按预期工作,但真正的目标是在单个递归函数中获得相同的结果。

显然,这不是一个真正的编程案例,而是 Python 初学者书籍中的一项任务,我完全被困住了。我想这个问题的尴尬标题反映了我对这个问题缺乏理解。

【问题讨论】:

  • 首先您可以更新问题以整理缩进。其次,您能解释一下snowflake(...) 是什么吗?看起来像函数调用,但没有定义。
  • Upps,谢谢,完成
  • 好的,这目前不是递归的。您的意思是让fract() 函数调用自身吗?它目前正在调用koch_loop(),其参数看起来像是可以调用自己。
  • sigh ...提醒自己:不要在尚未完全清醒时发布问题

标签: python recursion turtle-graphics fractals


【解决方案1】:

假设您的fract() 函数应该调用自己,那么我已经能够成功运行您的代码。

您所做的是定义一个递归函数fract(),它被您的circle() 函数多次调用。这称为组合函数。这是一件好事。

您的每个函数都有严格定义的行为,即它们是有凝聚力的。这意味着其他程序员可以选择您的函数(尤其是fract())并在他们自己的程序中重用它们。

我的意见是最好有许多小的内聚函数(以及类和模块),它们可以以比最初预期更多的方式组合。

【讨论】:

  • 谢谢@quamrana!虽然很高兴听到我的解决方案似乎足够,但我想知道是否有可能在单个递归函数中解决此任务。我尝试引入深度计数器,并根据深度改变最后一个角度,即。 e.当depth % 2 == 0改成t.right(120),但无济于事。
  • 虽然它可能的,但您将在 fract() 函数中嵌入您的 circle() 函数的一部分,这会将它变成一个不同的函数,我的理论 其他程序员将不再能够重用。
【解决方案2】:

我同意@quamrana 在这件事上的观点,但让我们解决可能是个难题的问题。有点诡计。

首先,您的合并函数必须采用四个参数,因为 circle()order 参数与 fract()order 参数无关。我们将其中的第一个重命名为 sides(),因为它代表的就是它。

其次,您的fract() 函数并非完全递归,它在内部使用迭代。我将在我的解决方案中遵循相同的模式。

最后,我们需要一些隐藏信息来处理——你可以使用默认的第五个参数,它会在内部发生变化,但我将使用 sides 的类型来实现这个结果:

import turtle as t

def fract(t, sides, order, size):

    if order == 0:
        t.forward(size)

    elif sides is not None:
        for _ in range(sides):
            fract(t, None, order, size)
            t.right(360 / sides)
    else:
        for angle in (60, -120, 60, 0):
            fract(t, None, order - 1, size / 3)
            t.left(angle)

t.speed('fastest')  # because I have no patience

fract(t, 4, 2, 300)

t.hideturtle()

t.exitonclick()

我相信这可以通过对原始代码的最小更改来实现您想要的结果。除了生成原始图形的fract(t, 4, 2, 300) 调用之外,我们还可以做类似fract(t, 3, 3, 300) 的变体:

您可能要解决的下一个问题是如何使这些图像在屏幕上居中,这样fract(t, 5, 1, 300) 就不会掉出边缘。

【讨论】:

    猜你喜欢
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 2021-11-28
    • 2015-08-09
    • 2017-05-09
    • 2022-10-15
    • 1970-01-01
    相关资源
    最近更新 更多