我正在经历麻省理工学院领导蟒蛇课程的问题3,而且我有一个公认的漫长的剧本,感觉它已经接近了。我需要打印s中最长的子串,其中字母按字母顺序出现。我能够根据它旁边的字符拉出任何按字母顺序排列的字符。我需要看到的是:
输入:'aezcbobobegghakl'
需要的输出:'beggh'
我的输出:['a', 'e', 'b', 'b', 'b', 'e', 'g', 'g', 'a', 'k']
我的代码:
s = 'aezcbobobegghakl'
a = 'abcdefghijklmnopqrstuvwxyz'
len_a = len(a)
len_s = len(s)
number_list = []
letter_list = []
for i in range(len(s)):
n = 0
letter = s[i+n]
if letter in a:
number_list.append(a.index(letter))
n += 1
print(number_list)
for i in number_list:
letter_list.append(a[i])
print(letter_list)
index_list = []
for i in range(len(letter_list)):
index_list.append(i)
print(index_list)
first_check = []
for i in range(len(letter_list)-1):
while number_list[i] <= number_list[i+1]:
print(letter_list[i])
first_check.append(letter_list[i])
break
print(first_check)
我知道在查看有更短且完全不同的方法来解决问题后,但为了我的理解,是否有可能完成此代码以获得我正在寻找的输出?或者这只是我挖过的兔子漏洞?
我会建立一个生成器输出所有字符运行,如l[i] >= l[i-1]
。然后找到最长的那些运行。就像是
def runs(l):
it = iter(l)
try:
run = [next(it)]
except StopIteration:
return
for i in it:
if i >= run[-1]:
run.append(i)
else:
yield run
run = [i]
yield run
def longest_increasing(l):
return ''.join(max(runs(l), key=len))
编辑:关于代码的注释
for i in range(len(s)):
n = 0
letter = s[i+n]
if letter in a:
number_list.append(a.index(letter))
n += 1
得到每个字母的“数字值”。您可以使用ord
函数来简化此操作
number_list = [ord(c) - 97 for c in s if c.islower()]
你永远不会使用index_list
,你永远不应该。看看enumerate
功能。
first_check = []
for i in range(len(letter_list)-1):
while number_list[i] <= number_list[i+1]:
print(letter_list[i])
first_check.append(letter_list[i])
break
这一部分没有多大意义。你break
每次都在while
循环中,所以它基本上是一个if
。您无法跟踪多个运行。这里没有用于比较字符串相互比较的机制。我想你可能会尝试做类似的事情
max_run = []
for i in range(len(letter_list)-1):
run = []
for j in range(i, len(letter_list)):
run.append(letter_list[j])
if letter_list[j] > letter_list[j+1]:
break
if len(run) > len(max_run):
max_run = run
(免责声明:我很确定上面的内容是关闭的,但它应该是说明性的)。以上可以通过很多方式得到改善。请注意,它循环遍及len(s)
次的最后一个字符,使其成为n**2
解决方案。另外,我不确定为什么你需要number_list
,因为字符串可以直接比较。
简单的递归方法怎么样:
data = 'ezcbobobegghakl'
words=list(data)
string_s=list(map(chr,range(97,123)))
final_=[]
def ok(list_1,list_2):
if not list_1:
return 0
else:
first = list_1[0]
chunks = list_2[list_2.index(first):]
track = []
for j, i in enumerate(list_1):
if i in chunks:
track.append(i)
chunks=list_2[list_2.index(i):]
else:
final_.append(track)
return ok(list_1[j:],list_2)
final_.append(track)
print(ok(words,string_s))
print(max(final_,key=lambda x:len(x)))
输出:
['b', 'e', 'g', 'g', 'h']
您可以找到输入字符串的所有子字符串列表,然后查找按字母顺序排序的所有字符串。要确定字母按字母顺序排序,按字母表中的位置对原始字符串进行排序,然后查看最终字符串是否等于原始字符串:
from string import ascii_lowercase as l
s = 'aezcbobobegghakl'
substrings = set(filter(lambda x:x, [s[i:b] for i in range(len(s)) for b in range(len(s))]))
final_substring = max([i for i in substrings if i == ''.join(sorted(list(i), key=lambda x:l.index(x)))], key=len)
输出:
'beggh'
这是完成工作的一种方法:
s = 'aezcbobobegghakl'
l = list(s)
run = []
allrun = []
element = 'a'
for e in l:
if e >= element:
run.append(e)
element = e
else:
allrun.append(run)
run = [e]
element = e
lengths = [len(e) for e in allrun]
result = ''.join(allrun[lengths.index(max(lengths))])
“跑”基本上是一个不间断的运行;当你添加比之前看到的更大的元素时,它会不断增长(“b”大于“a”,只是字符串比较),然后重置其他元素。
“allrun”包含所有“run”,如下所示:
[['a', 'e', 'z'], ['c'], ['b', 'o'], ['b', 'o'], ['b', 'e', 'g', 'g', 'h']]
“结果”最终选择“allrun”中最长的“run”,并将其合并为一个字符串。
关于你的代码:
这是非常低效的,我不会继续它。我会采用其中一个发布的解决方案。
您的number_list可以写成[a s的索引(_)],一个班轮。
你的letter_list实际上只是list(s),你正在使用循环!
你的index_list,它甚至做了什么?它相当于range(len(letter_list)),那么你在循环中追加什么?
最后,你编写循环的方式让我想起了matlab。您可以只迭代列表的元素,无需迭代索引并获取列表中的相应元素。