我尝试编写一个函数,该函数将字符串s
作为输入,并返回s
中按字母顺序排列的子字符串列表。例如,s = 'acegibdh'
应返回['acegi', 'bdh']
。
这是我提出的代码:
s = 'acegibdh'
ans = []
subs = []
i = 0
while i != len(s) - 1:
while s[i] < s[i+1]:
subs.append(s[i])
i += 1
if s[i] > s[i-1]:
subs.append(s[i])
i += 1
subs = ''.join(subs)
ans.append(subs)
subs = []
print ans
由于i + 1测试超出了索引范围,它一直遇到字符串的最后一个字母的问题。我花了很长时间来修补它,试图找到一种方法来避免这个问题。有谁知道怎么做?
答案 0 :(得分:4)
为什么不将第一个字母硬编码到ans
,然后只使用字符串的其余部分?您可以迭代字符串本身而不是使用索引。
>>> s = 'acegibdh'
>>> ans = []
>>> ans.append(s[0])
>>> for letter in s[1:]:
... if letter >= ans[-1][-1]:
... ans[-1] += letter
... else:
... ans.append(letter)
...
>>> ans
['acegi', 'bdh']
答案 1 :(得分:1)
s = 'acegibdh'
ans = []
subs = []
subs.append(s[0])
for x in range(len(s)-1):
if s[x] <= s[x+1]:
subs.append(s[x+1])
if s[x] > s[x+1]:
subs = ''.join(subs)
ans.append(subs)
subs = []
subs.append(s[x+1])
subs = ''.join(subs)
ans.append(subs)
print ans
如果您有任何问题,我决定稍微更改您的代码
答案 2 :(得分:1)
只是为了好玩,一线解决方案。
>>> s='acegibdh'
>>> [s[l:r] for l,r in (lambda seq:zip(seq,seq[1:]))([0]+[idx+1 for idx in range(len(s)-1) if s[idx]>s[idx+1]]+[len(s)])]
['acegi', 'bdh']
答案 3 :(得分:0)
不止一个while循环过度杀伤。我认为这更简单,满足您的要求。注意,这在空字符串上失败。
s = 'acegibdh'
ans = []
current = str(s[0])
i = 1
while i < len(s):
if s[i] > s[i-1]:
current += s[i]
else:
ans.append(current)
current = ''
i += 1
if current != '':
ans.append(current)
print ans
答案 4 :(得分:0)
您应该尝试避免每次迭代多次增加位置的循环。
通常更清楚的是引入一个额外的变量来存储有关先前状态的信息:
s = 'acegibdh'
prev = None
ans = []
subs = []
for ch in s:
if prev is None or ch > prev:
subs.append(ch)
else:
ans.append(''.join(subs))
subs = [ch]
prev = ch
ans.append(''.join(subs))
我认为这更直接地读取(如果没有先前的字符,或者它仍然按字母顺序添加当前字符串,否则启动一个新的子字符串)。此外,您也无法通过此approch获得索引超出范围的问题。
答案 5 :(得分:0)
只是为了好玩,因为我喜欢做一些有点不同的事情
from itertools import groupby,chain,cycle
def my_gen(s):
check = cycle([1,0])
for k,v in groupby(zip(s,s[1:]),lambda x:x[0]<x[1]):
if k:
v = zip(*v)
yield v[0] + (v[1][-1],)
print list(my_gen('acegibdhabcdefghijk'))
答案 6 :(得分:0)
发布的某些解决方案对空字符串有索引错误。
此外,您可以跟踪解决方案子字符串的起始索引i
,而不是保留字符列表或重复字符串连接,并在s[i:j]
处生成s[j] < s[j-1]
,然后将i
设置为j
。
当下一个字母按字典顺序小于前一个字母时生成子字符串的生成器:
def alpha_subs(s):
i, j = 0, 1
while j < len(s):
if s[j] < s[j-1]:
yield s[i:j]
i = j
j += 1
if s[i:j]:
yield s[i:j]
print(list(alpha_subs('')))
print(list(alpha_subs('acegibdh')))
print(list(alpha_subs('acegibdha')))
[]
['acegi', 'bdh']
['acegi', 'bdh', 'a']
对于不区分大小写:
def alpha_subs(s, ignore_case=False):
qs = s.lower() if ignore_case else s
i, j = 0, 1
while j < len(s):
if qs[j] < qs[j-1]:
yield s[i:j]
i = j
j += 1
if s[i:j]:
yield s[i:j]
print(list(alpha_subs('acEgibDh', True)))
print(list(alpha_subs('acEgibDh')))
['acEgi', 'bDh']
['ac', 'Egi', 'b', 'Dh']