首先,这些:
def strHead(s):
"""strHead: String -> String"""
return s[0]
def strTail(s, run):
"""strTail: String -> String"""
return s[:]
他们没有做任何有用的事情;第一个返回项目 0,第二个只返回字符串。查克他们。
然后
def runLenAux(s, c):
if s == "":
return 0
else:
if strHead(s)== c:
return 1 + int(runLenAux(strTail(s), c))
else:
return 0
现在有一个明显的问题。当它们充其量是数字列表时,您将它们视为数字。但是其他时候,您将它们视为字符串。
让我们将它们视为列表,因为这样更明显。
所以:
def runLenAux(s, c):
s
和是什么c
?不知道。我想这是为了获得下一个值,所以做一个[1, 0] → [1, 1, 1, 0]
映射。所以让它列出一个清单:
def look_and_say(term):
"""Looks at and says a term."""
->
在 Python 3 中,您可以对函数进行注释,而不是做有趣的事情。通过向他们展示这个半隐晦的事实来打动您的同龄人!
def look_and_say(term: "[int]") -> "[int]":
"""Looks at and says a term."""
在这里,我"[int]"
用来表示“a list
of int
s”。
所以,进入下一部分:
if s == "":
return 0
天哪!你打算使用递归吗?!这太多了!我们不是这里的Haskell!
好的,从顶部开始。我们想要遍历,记录我们见过多少相同的项目,是吗?所以我们可以做一个像这样的循环:
for item in term:
count how many are the same
if different, break
(这听起来像是以前做过的事情。嗯,它已经完成了。它被称为itertools.groupby
。不过,让我们假装你不知道。)
count = 0
match = None
for item in term:
# If this isn't the same we should stop counting
if match != item:
do_something_with_count_and_match
# Start again from this item
count = 1
match = item
# If this is the same we should continue counting
else:
count = count + 1
这看起来不错!
放什么do_something_with_count_and_match
?好吧,让我们保留一份清单,把东西放进去,然后把我们的结果放在那里
# This is what we're building
next_term = []
...
for item in term:
...
if match != item:
# Say "One One" or "Two Threes" or "Three Ones", etc.
next_term.append(count)
next_term.append(match)
# Start again from this item
count = 1
match = item
...
那么,它运行了吗?
def look_and_say(term: "[int]") -> "[int]":
"""Looks at and says a term."""
# This is what we're building
next_term = []
count = 0
match = None
for item in term:
# If this isn't the same we should stop counting
if match != item:
# Say "One One" or "Two Threes" or "Three Ones", etc.
next_term.append(count)
next_term.append(match)
# Start again from this item
count = 1
match = item
# If this is the same we should continue counting
else:
count = count + 1
look_and_say([0])
#>>>
嗯……没有输出。
啊,我们忘记return
了next_term
:
def look_and_say(term: "[int]") -> "[int]":
... # All that stuff
return next_term
look_and_say([0])
#>>> [0, None]
嗯..那不好。我们需要确保我们没有计算None
占位符match
:
def look_and_say(term: "[int]") -> "[int]":
...
for item in term:
...
if match != item:
if match is not None:
next_term.append(count)
next_term.append(match)
...
...
我们还需要添加最后一部分,即使它不会触发else
(循环将停止):
def look_and_say(term: "[int]") -> "[int]":
...
for item in term:
...
if match != item:
if match is not None:
next_term.append(count)
next_term.append(match)
return next_term
那就试试吧:
def look_and_say(term: "[int]") -> "[int]":
"""Looks at and says a term."""
# This is what we're building
next_term = []
count = 0
match = None
for item in term:
# If this isn't the same we should stop counting
if match != item:
# Say "One One" or "Two Threes" or "Three Ones", etc.
if match is not None:
next_term.append(count)
next_term.append(match)
# Start again from this item
count = 1
match = item
# If this is the same we should continue counting
else:
count = count + 1
if match is not None:
next_term.append(count)
next_term.append(match)
return next_term
look_and_say([0])
#>>> [1, 0]
look_and_say([1, 0])
#>>> [1, 1, 1, 0]
look_and_say([1, 1, 1, 0])
#>>> [3, 1, 1, 0]
是的!
我这样做是为了向您展示编程不是魔术。你只需要不断尝试和应用你所知道的。
我个人会这样实现它:
from itertools import groupby
# What we just implemented
def look_and_say(string):
for k, v in groupby(string):
yield sum(1 for _ in v)
yield k
list(look_and_say([0]))
#>>> [1, 0]
list(look_and_say([1, 0]))
#>>> [1, 1, 1, 0]
list(look_and_say([1, 1, 1, 0]))
#>>> [3, 1, 1, 0]
但这只是因为我知道groupby
。