def abc(s):
filter = [i for i in s.lower() if i in 'abcdefghijklmnopqrstuvwxyz']
for i in range(len(filter) - 1):
if filter[i] > filter[i+1]:
return print(s, "is not abcdearian")
return print(s, "is abcdearian")
while True:
try:
s = input("String? ")
abc(s)
我在制作abc(s)的递归版本时遇到了麻烦。有什么想法吗?
答案 0 :(得分:3)
非递归解决方案:
def issorted(L):
return all(x <= y for x, y in zip(L, L[1:]))
要制作递归函数,您应该找到一种方法将问题拆分为更小和/或更简单的子问题,这些问题可以通过相同的方式解决:
#!/usr/bin/env python3
from string import ascii_lowercase
def abcdearian(s):
return issorted_recursive([c for c in s.lower() if c in ascii_lowercase])
def issorted_recursive(L):
return L[0] <= L[1] and issorted_recursive(L[1:]) if len(L) > 1 else True
这里issorted_recursive()
是一个递归函数。基本情况为len(L) <= 1
(具有零个或一个元素的列表始终排序,因此在这种情况下返回True
)。在递归情况(len(L) > 1
)中,如果第一个项目处于排序顺序(L
)并且列表的其余部分,则列表L[0] <= L[1]
被视为已排序(L[1:]
)也已排序。每次函数接收越来越小的输入,直到找到乱序元素(L[0] > L[1]
)或遇到基本情况并且函数结束。
while True:
s = input("String? ")
if not s:
break
print("{} is {}abcdearian".format(s, "" if abcdearian(s) else "not "))
abc bac
String? abc is abcdearian
String? bac is not abcdearian
String?
答案 1 :(得分:0)
尝试使用此代码,它相当于问题中发布的代码,但是以递归方式编写:
from string import ascii_lowercase
def abc(s):
f = [c for c in s.lower() if c in ascii_lowercase]
if aux(f, 0):
return s + " is abcdearian"
else:
return s + " is not abcdearian"
def aux(s, i):
if i >= len(s)-1:
return True
elif s[i] > s[i+1]:
return False
else:
return aux(s, i+1)
像这样使用:
while True:
s = input("String? ")
if not s:
break
print(abc(s))
请注意,我将问题分成两部分:首先,“main”函数abc()
负责过滤字符串,使用正确的初始值调用aux
过程并返回结果字符串。结束(或者:你可以返回一个布尔值,在别处创建结果字符串。)
真正的工作是在helper aux
函数中完成的,如果字符串中所有连续字符对的“abcdearian”条件为真,则递归遍历字符串检查。 aux
遍历字符串的方式是有效的(抛开我们使用递归的事实),因为它永远不会使用s[1:]
创建额外的中间字符串。它也是tail-recursive算法的一个例子,它与迭代解决方案的结构密切相关。
答案 2 :(得分:0)
最初编写接受的答案的方式似乎过于复杂。我已经提交了一个希望修复它的编辑。但是当我意识到这一点时,我已经写了下面的答案和解释。保留它,以防解释对某人有用:
def abc(s):
filtered = [i for i in s.lower() if i in 'abcdefghijklmnopqrstuvwxyz']
optionalNotString = ('' if _abc(filtered) else ' not')
print( '{0} is{1} abcdearian'.format( repr(s), optionalNotString ) )
# Recursively process the "rest" (remainder) of the string.
# At each step, examine the first two characters.
def _abc(rest):
if len(rest) < 2:
# We've successfully compared all successive pairs, so return True.
return True
if (rest[0] > rest[1]):
return False
return _abc(rest[1:])
在使用中(最重要的情况是测试,包括太短的字符串,并在字符串'acb'的末尾检测到错误状态,以及字符串'bac'的开头。我有一个错误第一个我编写它的方式,未能将'bac'视为False!):
abc( '' )
abc( 'a' )
abc( 'ac' )
abc( 'abc' )
abc( 'acb' )
abc( 'bac' )
输出:
'' is abcdearian
'a' is abcdearian
'ac' is abcdearian
'abc' is abcdearian
'acb' is not abcdearian
'bac' is not abcdearian
说明:
过滤只需要进行一次,所以在主“abc”函数中进行,而不是在递归的“_abc”函数中进行。
在每个步骤中,算法需要查看两个相邻的字符。在每次调用“_abc”时,这些都是前两个字符。
“_ abc”需要处理两种情况:
案例1:字符串太短而无法进行比较。例如。 ''或'a'。这样的字符串满足abcderian标准,因此返回True。
案例2:字符串至少有两个字符。执行前两个的abcderian计算。如果失败,答案是假的。否则,使用除第一个字符以外的所有字符递归。
“repr(s)”是一种简单的方法,可以使用周围的引号来打印“s”。
“optionalNotString”:True / False情况下的所需答案字符串仅因“not”的存在/不存在而不同。因此,使用“if .. else ..”表达式来控制格式化输出中是否包含“not”。如果不需要,请替换空字符串''。