最长的字母子字符串 - 从哪里开始



我正在研究流行的麻省理工学院课程中的"最长字母子字符串"问题。 我已经阅读了很多关于SO如何编码的信息,但我真的很难在概念上实现飞跃。 之前的手指练习并不太难。 我想知道是否有人知道任何材料可以真正分解这个问题中使用的问题解决方案。 我试着拿出笔和纸,我只是迷路了。 我看到人们使用各种"计数器",或包含"迄今为止最长的子字符串"的字符串,当我查看其他人的解决方案时,我可以理解他们对代码做了什么,但是如果我尝试合成我自己的东西,它只是没有点击。

我甚至从课程中休息了一下,并尝试通过其他一些书籍学习,但我不断回到这个问题,觉得我需要突破它。 我想我正在努力解决的是实现从了解一些Python语法和工具到实际使用这些工具有机地解决问题或"计算"的飞跃。

在任何人指出我之前,我知道旨在提供帮助的课程材料。 我看过其中一位助教制作的一些视频,这些视频有些帮助,但他并没有真正分解这一点。 我觉得我需要与某人或类似的人配对编程......坐在白板前,让别人一步一步地引导我,回答我会遇到的每一个愚蠢的问题。

作为参考,问题如下:

假定 s 是小写字符的字符串。

编写一个程序,打印 s 的最长子字符串,其中字母按字母顺序出现。例如,如果 s = 'azcbobobegghakl',那么你的程序应该打印

按字母顺序排列的最长子字符串是:beggh

如果是领带,请打印第一个子字符串。例如,如果 s = 'abcbcd',那么您的程序应该打印

按字母顺序排列的最长子字符串是:abc

我知道发布代码很有帮助,但我没有任何 SO 其他地方没有的东西,因为这就是我一直在 IDE 中玩的东西,看看我是否可以理解发生了什么。 同样,不是寻找代码片段 - 更多的是一些阅读或资源,这些阅读或资源将扩展此问题中使用的逻辑。 我会发布我所拥有的,但它并不完整,在我开始感到困惑之前

,我已经得到了。
s = 'azcbobobegghakl'
current = s[0]
longest = s[0]
for letter in range(0, len(s) -1):
if s[letter + 1] >= s[letter]:
current.append(s[letter + 1])
if len(current) > len(longest):
longest = current
else:
current = 

很抱歉格式错误,仍然是新的。 我对这个问题感到非常沮丧。

你几乎在你的例子中,只需要一点调整

s = 'azcbobobegghakl'
longest = [s[0],]  # make them lists so we can manipulate them (unlike strings)
current = [s[0],]
for letter in range(0, len(s) -1):
if s[letter + 1] >= s[letter]:
current.append(s[letter + 1])
if len(current) > len(longest):
longest = current
else:
current = [s[letter+1],]  # reset current if we break an alphabetical chain
longest_string = ''.join(longest)  # turn out list back into a string

longest_string输出:

'beegh'

如果你正在为解决这个问题背后的概念和逻辑而苦苦挣扎,我建议你退后一步,通过更简单的编码教程和交互式练习。您可能还喜欢尝试JavaScript,从一开始就可能更容易发挥创意,构建可以在浏览器中立即与之交互的片段和/或网页。然后,当您获得更多有趣的编码词汇时,它的算法部分将看起来更加熟悉和自然。我也认为让你自己的创造力和想象力指导你是一个非常强大的学习过程。

让我们暂时忘记按字母顺序排列的部分。想象一下,我们有一袋字母,我们一次拿出一个,不知道下一个是哪个,我们必须连续记录最长的R。你会怎么做?让我们尝试用文字描述这个过程,然后是伪代码。

我们将保留一个容器,用于迄今为止我们看到的最长运行,另一个用于检查当前运行。我们拉动字母,直到我们连续达到两个R,我们将其放入"当前"容器中。下一个字母不是R,这意味着我们的运行结束了。"到目前为止最长"的运行是空的,因此我们将"当前"容器倒入其中并继续。接下来的四个字母不是R,所以我们只是忽略它们。然后我们得到一个R,我们将其放入"当前"中,然后放入H.我们的运行再次结束,但这次我们在"当前"中的一R比我们在"迄今为止最长"中的两个要少,所以我们保留这些和空的"当前"。

我们得到一个A,一个B,和一个C,然后运行五Rs,我们一个接一个地放入"当前"容器中。我们的包现在包含最后一个字母,一个T。我们看到我们的运行再次结束,并且"当前"容器比"到目前为止最长"的容器更多,因此我们倒出"最长"并将其内容替换为"当前"中的五个R。就是这样,我们在袋子里找到了最长的R。(如果我们有更多的运行,每次运行结束时,我们都会选择是否替换"到目前为止最长"的内容。

在伪代码中:

// Initialise
current <- nothing
longest <- nothing
for letter in bag:
if letter == 'R':
add 'R' to current
else:
if there are more letters
in current than longest:
empty longest and pour
in letters from current
otherwise:
empty current to get ready
for the next possible run

现在,按字母顺序排列的规定只是使我们的状况稍微复杂化。我们需要跟踪放在"当前"中的最新字母,并且为了继续运行,它看不到另一个相同的字母。相反,下一个字母必须比我们放在当前位置的最后一个字母"更大"(按字典顺序排列);否则,运行结束,我们针对"到目前为止最长"执行数量检查。

通常,从输入中创建所有可能性的列表,然后根据所需的其他逻辑过滤结果会更容易。例如,在查找最长的子字符串时,可以找到输入的所有子字符串,然后仅保留有效序列的元素:

def is_valid(d):
return all(d[i] <= d[i+1] for i in range(len(d)-1))
def longest_substring(s):
substrings = list(filter(is_valid, [s[i:b] for i in range(len(s)) for b in range(len(s))]))
max_length = len(max(substrings, key=len)) #this finds the length length of the longest valid substring, to be used if a tie is discovered
return [i for i in substrings if len(i) == max_length][0]
l = [['abcbcd', 'abc'], ['azcbobobegghakl', 'beggh']]
for a, b in l:
assert longest_substring(a) == b
print('all tests passed')

输出:

all tests passed

对我来说,处理实现复杂性的一种方法是编写一些单元测试:在某些时候,如果我无法从"阅读代码"中找出问题所在,和/或缺少哪些部分,我喜欢编写单元测试,这是一种解决问题的"正交"方法(而不是思考"我该如何解决这个问题?我问自己"我应该写什么测试来验证它是否正常工作?

然后,通过运行测试,我可以观察实现的行为方式,并尝试"一个接一个"地解决问题,即专注于使下一个单元测试通过。

这也是一种"在更容易推理的小问题中削减大问题"的方法。

s = 'azcbobobeggh'
ls = [] #create a new empty list
for i in range(len(s) - 1): # iterate s from index 0 to index -2
if s[i] <= s[i+1]: # compare the letters
ls.append(s[i]) # after comparing them, append them to the new list
else:
ls.append(s[i])
ls.append('mark') # place a 'mark' to separate them into chunks by order
ls.append(s[-1]) # get back the index -1 that missed by the loop
# at this point here ls:
# ['a', 'z', 'mark', 'c', 'mark', 'b', 'o', 'mark', 'b', 'o', 'mark', 'b', 'e', 'g', 'g', 'h']
ls = str(''.join(ls)) # 'azmarkcmarkbomarkbomarkbeggh'
ls = ls.split('mark') # ['az', 'c', 'bo', 'bo', 'beggh']
res = max(ls, key=len) # now just find the longest string in the list
print('Longest substring in alphabetical order is: ' + res)
# Longest substring in alphabetical order is: beggh

相关内容

最新更新