首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >双递归教育示例

双递归教育示例
EN

Stack Overflow用户
提问于 2015-06-20 05:02:41
回答 3查看 572关注 0票数 5

这个函数对我来说没有任何意义。我到处都添加了打印语句来弄清楚到底是怎么回事,但我还是不明白。如果有人能给我解释一下,我将不胜感激。

代码语言:javascript
运行
复制
def f(s):
    if len(s) <= 1:
        return s
    return f(f(s[1:])) + s[0]

print(f("mat"))

这就是我所看到的情况。因此,我们从长度为3的字符串开始,绕过if语句。我们首先处理内部的f(s1:)。所以现在我们有一个长度为2的字符串("at"),它再次绕过if语句并进入f(s1),它给出了长度为1 ( "t“)的字符串,最终进入if语句并返回”t“。对我来说,这就是线索停止的地方。

从我的print语句中,我看到创建了一个长度为2的新字符串,并返回随后的"a“。最终的产品是"atm“。多亏了"+ s“部分,我得到了末尾的"m”标记,但为什么是"atm“而不是"tam"?

老实说,我已经在这上面花了几个小时,但我不能让它下雨。任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2015-06-20 05:40:40

通过在函数调用中填充它们正在做的事情,将整个过程扩展到很长的步骤中。从最深处/最深处开始处理括号。在加法前处理函数调用。

为了清楚起见,我将忽略所有地方的字符串引号。

代码语言:javascript
运行
复制
f(mat)           -> mat is 3 chars:
                    call f on at for f(at), and call f on that.
                    add m.

f(f(at))+m       -> inner f(at), at is 2 chars:
                    call f on t for f(t), and call f on that.
                    add a.

f(f(f(t))+a)+m   -> innermost f(t) returns t.

f(f(t)+a)+m      -> inner f(t) returns t as well.

f(ta)+m          -> [here, the first f(f(at)) has been reduced to f(ta)]
                    ta is 2 chars:
                    call f on a for f(a), and call f on that.
                    add t.

f(f(a))+t+m      -> inner f(a) returns a.

f(a)+t+m         -> f(a) returns a as well.

a + t + m        -> 

atm              -> everything reduces to atm.
票数 5
EN

Stack Overflow用户

发布于 2015-06-20 05:06:48

简而言之:at交换了两次,因此内部f("at")调用返回"ta",然后外部f()调用传递"ta"并返回"at"

更长的版本:我不会明确地为你解释,因为你不会学到那么多东西,但考虑这个函数,它是完全等价的

代码语言:javascript
运行
复制
def f2(s):
    if len(s) <= 1:
        return s
    x = f2(s[1:])
    return f2(x) + s[0]

print(f2("mat"))

当您调用f2("mat")时,s[1:]"at"。现在,f2("at")返回什么呢?将该值(x的值)插入到f2(x) + s[0]表达式中,看看会得到什么。

尝试遍历f2("at")f2("ta")的值,看看是否能发现发生了什么。如果你在另一个15-20分钟的工作后仍然需要帮助,请评论这个答案,我将进一步扩展它。

票数 1
EN

Stack Overflow用户

发布于 2015-06-20 06:30:16

这实际上是一个令人惊讶的有趣的函数,我可以理解为什么它会让您感到困惑。我假设您试图将函数作为一个整体来理解,而这在这里实际上不会很好地工作。

现在,这个函数有两个部分-处理它为空或字符串中只有一个字母的情况,以及处理字符串中至少有两个字母的情况。然而,这是欺骗性的,因为它根据字符串中有多少个字母有效地应用了不同的操作!

因此,让我们以一种非递归的方式来考虑这个函数:如果字符串太短,就返回该字符串。否则,将某个函数应用于字符串中除第一个字符之外的所有字符两次,然后将第一个字符添加到结果的末尾。不要认为它是同一个函数,只要把它看作是某个未知的函数就行了。

在代码中:

代码语言:javascript
运行
复制
def f(s):
    if len(s) <= 1:
        return s
    return other_f(other_f(s[1:])) + s[0]

进入兔子洞:

那么我们如何定义这个other_f呢?让我们看看对于特定的字符串长度,它需要具有什么样的行为。如果len(s)是2,那么我们知道s[1:]是一个字符,所以other_f将只返回s[1:]。在代码中:

代码语言:javascript
运行
复制
def f2(s): # For when len(s)==2
    #if statement is not used
    #return other_f(other_f(s[1:])) + s[0] becomes
    #return other_f(other_f(s[1])) + s[0] becomes
    #return other_f(s[1]) + s[0] becomes
    return s[1] + s[0]

它只是简单地交换这两个字母。让我们使用字符串'abc'来更容易地查看下一个字符串发生了什么:

代码语言:javascript
运行
复制
def f3(s): # For when len(s)==3
    #if statement is not used
    #return other_f(other_f(s[1:])) + s[0] becomes
    #return f2(f2('bc')) + 'a' becomes
    #return f2('cb') + 'a' becomes
    #return 'bc' + 'a'
    return s[1:] + s[0]

由于应用于'bc‘的函数会交换它们并应用两次,因此该函数会自行撤消。因此,在本例中,我们只需将第一个字母放在字符串的末尾。

代码语言:javascript
运行
复制
def f4(s): # For when len(s)==4
    #return f3(f3(s[1:])) + s[0] becomes
    #return f3(f3('bcd')) + 'a' becomes
    #return f3('cdb') + 'a' becomes
    #return f3('dbc') + 'a' becomes
    #'dbca'
    return s[3] + s[1:3] + s[0] # swap first and last letter

def f5(s): # For when len(s)==5
    #return f4(f4(s[1:])) + s[0]
    #return f4(f4('bcde')) + 'a'
    #swapping first and last letter twice just swaps then swaps back
    #return 'bcde' + 'a'
    return s[1:] + s[0]

因此,看起来我们得到了一个很好的模式--如果字符串的字母数是偶数,则交换第一个和最后一个字母。如果它的字母数为奇数,请将第一个字母移到末尾!

..。不是的。该模式以f5结尾。如果使用类似“abcd...”这样的字符串运行函数。您可以很容易地看到每个级别是如何移动字母的。

代码语言:javascript
运行
复制
f | output
----------
f6|'defbca'
f7|'cdbfgea'
f8|'cgefbhda'
f9|'fecihbgda'

如你所见,对于较长的字符串,除了第一个字符总是以字符串的末尾结束之外,其他字母都被打乱了。最好的办法是(用一行代码)为每个字符串长度编写一个不同的函数(其中一些函数的行为相同,如f3f5)。每个函数都依赖于它上面的函数,所以因为f6 on down可以很好地随机化字符串,所以每个后续函数也应该很好地随机化字符串。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30947216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档