使用递归仅将输入字符串的字母连接成单个输出字符串
Posted
技术标签:
【中文标题】使用递归仅将输入字符串的字母连接成单个输出字符串【英文标题】:Using recursion to concatenate ONLY the letters of an input string into a single output string 【发布时间】:2022-01-09 03:35:05 【问题描述】:“给定一个由字母和特殊字符/数字组成的字符串,使用递归将字母连接成一个字符串并返回。”
我的代码在下面,我仍在学习递归并一直在尝试跟踪它。我在这段代码中尝试了一堆不同的行,但我不知道如何修复我目前所拥有的:
def decoder(encryptedStr):
if len(encryptedStr) != 0:
if encryptedStr[0].isalpha() == True:
decoded = encryptedStr[0]
decoded.join(decoder(encryptedStr[1:]))
print(decoded)
else:
decoder(encryptedStr[1:])
我还没有让它返回任何东西,因为我正在努力解决我必须将新字母加入输出字符串的部分。而不是 .join 我也尝试过:
decoded += decoder(encryptedStr[1:])
但它不起作用 bc Nonetype??
【问题讨论】:
您在else
部分中缺少return
,但无论如何算法似乎都是错误的。
我认为这并不重要,但如果没有额外的步骤,基于一次一个字符递归的典型答案仅适用于具有 1000 个或更少字符的字符串。
Python 是学习递归的糟糕语言选择,原因有几个。反复切片字符串非常昂贵。即使您对解决该问题的智能高效算法有想法,decoder(encryptedStr[1:])
之类的表达式也将确保算法的时间复杂度不会优于 n^2。
一个简单的pythonic解决方案,没有递归将是def(encrypted_str): return ''.join(c for c in encrypted_str if c.isalpha())
。如果你真的想用递归来解决这个问题,我建议选择python以外的任何其他语言。
【参考方案1】:
您的主要问题是您没有 return
,但您的方法存在一些问题,这使得这比需要的更复杂。
在进行递归时先考虑尾部——你的结束条件是什么,你如何决定继续。通常使用这种方法,您可以执行以下操作:1) 处理列表中的单个值,2) 让递归方法处理其余部分,3) 组合结果。
这里尾先返回的一个简单指标是,如果字符串为空,则不返回任何内容:
def decoder(encryptedStr):
if len(encryptedStr) == 0:
return ""
...
现在,在每次运行中,我们都希望对一个字母进行操作,并将其余的传递给递归调用。忽略特殊字符要求,您会得到如下内容:
def decoder(encryptedStr):
if len(encryptedStr) == 0:
return ""
first = encryptedStr[0]
rest = decoder(encryptedStr[1:])
return first + rest
现在我们可以处理想要省略字母的特殊情况了。
def decoder(encryptedStr):
if len(encryptedStr) == 0:
return ""
first = encryptedStr[0]
rest = decoder(encryptedStr[1:])
if not first.isalpha():
first = ""
return first + rest
仅此而已!
一些重构的好处:
def clean(letter):
return letter if letter.isalpha() else ""
def decoder(encrypted):
if len(encrypted) == 0:
return ""
return clean(encrypted[0]) + decoder(encrypted[1:])
【讨论】:
【参考方案2】:这里有一堆问题:
我认为join
在这种情况下不会做你希望它做的事情。如果您想将一些字符串添加在一起,只需使用+=
。 join
将在 decoder(encryptedStr[1:])
返回的任何内容之间插入 decoded
字符。
您没有len(encryptedStr) == 0
的案例,因此它返回默认值None
。这就是为什么您不能将其结果附加到decoded
。
【讨论】:
【参考方案3】:如果无事可做,立即返回。否则,如果匹配条件,取第一个字母,并添加递归调用的结果(其中参数是当前加密的字符串,没有第一个字符)。
def decoder(encrypted):
if not encrypted:
return ''
decrypted = encrypted[0] if encrypted[0].isalpha() else ''
return decrypted + decoder(encrypted[1:])
print(decoder('Abc123rtZ5'))
结果是AbcrtZ
。
奖金信息(如 cmets 中提到的 @JonSG):
用print(decoder('A' * 1000))
运行它,你就会明白为什么递归对于这个任务来说是个坏主意。
【讨论】:
【参考方案4】:每个递归函数都必须有一个停止递归的基本条件,否则函数会无限调用自身。 仅将输入字符串的字母递归连接成单个输出字符串:
some_string = "I2L4o2v3e+P;y|t!o#n"
def decoder(encryptedStr, decoded = ""):
if len(encryptedStr) == 0: # Base condition
return decoded
if encryptedStr[0].isalpha():
decoded += encryptedStr[0]
return decoder(encryptedStr[1:], decoded)
# If the char in the index [0] is not a letter it will be sliced out.
return decoder(encryptedStr[1:], decoded)
print(decoder(some_string))
输出:
ILovePython
【讨论】:
以上是关于使用递归仅将输入字符串的字母连接成单个输出字符串的主要内容,如果未能解决你的问题,请参考以下文章