需要编写一个程序来打印变量的最长子字符串,其中字母按字母顺序出现。
例如。s = 'onsjdfjqiwkvftwfbx'
,它应该返回'dfjq'
。
作为初学者,代码编写如下:
y=()
z=()
for i in range(len(s)-1):
letter=s[i]
while s[i]<=s[i+1]:
letter+=s[i+1]
i+=1
y=y+(letter,)
z=z+(len(letter),)
print(y[z.index(max(z))])
但是,上面的代码将始终返回
IndexError: string index out of range.
它将产生所需的结果,直到我将其更改为range(len(s)-3)
.
想就以下方面寻求建议:
为什么
range(len(s)-1)
会导致这样的错误消息?为了照顾索引到 i+1,我已经将范围值减少了 1。 我的理由是,如果变量 s 的长度为 14,它的索引为 0-13,range(14( 产生值 0-13。但是,由于我的代码涉及 i+1 索引,因此范围减少了 1 以处理这部分。如何修改上面的代码以产生正确的结果。 如果
s = 'abcdefghijklmnopqrstuvwxyz'
,上面的代码带有range(len(s(-3(再次返回IndexError: string index out of range
。为什么?这段代码有什么问题?
任何帮助不胜感激~
超出范围索引的原因是,在您的内部while
循环中,您正在推进i
而不检查其范围。你的代码也非常低效,因为你有嵌套循环,而且你正在做很多相对昂贵的字符串连接。没有串联的线性时间算法如下所示:
s = 'onsjdfjqiwkvftwfbcdefgxa'
# Start by assuming the longest substring is the first letter
longest_end = 0
longest_length = 1
length = 1
for i in range(1, len(s)):
if s[i] > s[i - 1]:
# If current character higher in order than previous increment current length
length += 1
if length > longest_length:
# If current length, longer than previous maximum, remember position
longest_end = i + 1
longest_length = length
else:
# If not increasing order, reset current length
length = 1
print(s[longest_end - longest_length:longest_end])
关于"1":实际上,使用range(len(s)-2)
也应该有效。
range(len(s)-1)
中断的原因:
对于"onsjdfjqiwkvftwfbx",len()
将等于 18。不过,您可以引用的最大索引是 17(因为索引从 0 开始(。 因此,当您循环遍历"i"时,在某些时候,i 将增加到 17(对应于len(s)-1
(,然后在while
比较中尝试访问s[i+1]
(这是不可能的(。
关于"2":以下方法应该有效:
current_output = ''
biggest_output = ''
for letter in s:
if current_output == '':
current_output += letter
else:
if current_output[-1]<=letter:
current_output += letter
else:
if len(current_output) > len(biggest_output):
biggest_output = current_output
current_output = letter
if len(current_output) > len(biggest_output):
biggest_output = current_output
print(biggest_output)