我同意@MStodd:递归是不是在Python解决这个问题的方法。对于很长的列表,Python可能会溢出它的堆栈!但是,对于短名单应该没问题,如果你的老师给你这个问题,你需要这样做。
下面是你应该如何思考这个问题。每次递归调用您应该执行以下三件事之一:0)返回False
,因为您已经发现该列表未被排序; 1)返回True
,因为您已达到基本情况; 2)将工作分解并使其余问题以某种方式变小,直至达到基本情况。基本情况就是工作无法进一步细分的情况。
这里是一个梗概:
def recursive_check(lst, i):
# check at the current position "i" in list
# if check at current position fails, return False
# update current position i
# if i is at the end of the string, and we cannot move it any more, we are done checking; return true
# else, if i is not at the end of the string yet, return the value returned by a recursive call to this function
例如,下面是一个检查,看看是否有字符串中的字符'@'
功能。如果字符串中的任何位置没有@
,它应返回True
。
def at_check(s, i):
if s[i] == '@':
return False
i += 1
if i >= len(s):
return True
else:
return at_check(s, i)
我写了上面的内容,就像上面给出的轮廓一样。这是一个稍微短一些的版本,但它们的功能完全相同。
def at_check(s, i=0):
if i >= len(s):
return True
if s[i] == '@':
return False
return at_check(s, i+1)
编辑:请注意,我把i=0
在参数at_check()
。这意味着i
的“默认”值将为0.调用此函数的人只需拨打at_check(some_string)
即可,并且不会在第一次调用时显式传入0;默认参数将提供第一个0参数。
我们真的需要添加一个到i
的唯一时间是我们递归调用该函数的时候。我们加1的部分是重要的“打破工作”部分。我们还没有检查过的字符串部分是i
之后的部分,每部分调用该部分都会变小。我不知道你是否已经学会了“切片”,但是我们可以使用“切片”来实际使每次调用时字符串变得越来越小。这是一个可以这样工作的版本;如果您还不知道切片,请忽略它。
def at_check(s):
if s == '': # empty string
return True
if s[-1] == '@': # is last character '@'?
return False
return at_check(s[:-1]) # recursive call with string shortened by 1
在此版本中,空字符串是基本情况。一个空字符串不包含@
,所以我们返回True
。那么如果最后一个字符是@
,我们可以返回False
;但除此之外,我们砍掉最后一个字符并递归调用该函数。在这里,我们通过从字面上使字符串变得越来越短来分解工作,直到完成。但是将1加入索引变量,并通过字符串移动索引,将是同样的事情。
研究这些示例,直到您得到使用递归来分解工作并在每次递归调用中取得进展的想法。然后看看你是否可以想出如何将这个想法应用于查找列表是否被排序的问题。
祝你好运!
感谢您的洞察力。我会尽力处理逻辑,看看我能想出什么。 – captainHawk 2012-07-24 17:05:55