面试问题:反转字符串,但仅反转字母字符。整数应保持其原始位置。
输入:“ abc12de” 输出:“ edc12ba”
输入:“ abcde79” 输出:“ edcba79”
输入:“ 123ab456” 输出:“ 123ba456”
下面是我的一半代码。
def reverse_string(string):
acc = ""
l = []
l.extend(string)
for char in l:
if char >= 0 and char <= 9:
pass
else:
acc = char + acc
return acc
print(reverse_string("abc12de"))
答案 0 :(得分:3)
一种策略可能是从两端遍历指针以跳过数字。当找到两个非数字时,请交换。当指针相遇时停止。您只需要注意当字符串为全数字/字母时可能发生的边缘情况:
def rev(st):
s = list(st)
i = 0
j = len(s)-1
while i < j:
while (i < len(s) and s[i].isdigit() ):
i += 1
while (j >=0 and s[j]. isdigit()):
j -= 1
if i < j:
s[j], s[i] = s[i], s[j]
i += 1
j -= 1
return ''.join(s)
print(rev('123ab456'))
print(rev('abc12de'))
print(rev('abcde79'))
print(rev('1234'))
print(rev('abcd'))
结果
123ba456
edc12ba
edcba79
1234
dcba
(也许)效率较低,但更易于阅读的替代方法是使所有字母的生成器以相反的顺序生成,然后逐步处理字符串,并使用生成器中的next()
字母作为字母或当前字符(如果是数字)
def rev(string):
reversed_letters = (s for s in string[::-1] if s.isalpha())
news = ''
for s in string:
if s.isalpha():
news+= next(reversed_letters)
else:
news += s
return news
答案 1 :(得分:0)
def matrix_in_spiral_order(square_matrix):
SHIFT = ((0,1),(1,0),(0,-1),(-1,0))
direction = x = y = 0
spiral_ordering = []
for _ in range(len(square_matrix)**2):
spiral_ordering.append(square_matrix[x][y])
square_matrix[x][y] = 0
next_x,next_y = x + SHIFT[direction][0], y+ SHIFT[direction][1]
if (next_x not in range(len(square_matrix)) or next_y not in range(
len(square_matrix)) or square_matrix[next_x][next_y] == 0):
direction = (direction +1) & 3
next_x, next_y = x+ SHIFT[direction][0], y + SHIFT[direction][1]
x,y = next_x, next_y
return spiral_ordering
测试:
def reverse_string(string):
num_char_pos = []
out_s = ""
for i, ch in enumerate(string):
if not ch.isalpha():
num_char_pos.append((ch, i))
else:
out_s += ch
out_s = out_s[::-1]
for numchar in num_char_pos:
out_s = out_s[:numchar[1]] + numchar[0] + out_s[numchar[1]:]
return out_s
结果:
输入:abc12de预期输出:edc12ba实际输出:edc12ba通过?:True
输入:abcde79预期输出:edcba79实际输出:edcba79通过?:是
输入:123ab456预期输出:123ba456实际输出:123ba456通过?:是
答案 2 :(得分:0)
这是我想到的第一个想法:
>>> def reverse_non_digits(text):
array = list(text)
other = [index for index, value in enumerate(array) if not value.isdecimal()]
for a, b in zip(other, reversed(other)):
if a >= b:
break
array[a], array[b] = array[b], array[a]
return ''.join(array)
>>> reverse_non_digits('abc12de')
'edc12ba'
>>> reverse_non_digits('abcde79')
'edcba79'
>>> reverse_non_digits('123ab456')
'123ba456'
>>>
下一版本的灵感来自Mark Meyer的approach:
>>> def reverse_non_decimal(text):
array, start, stop = list(text), 0, len(text) - 1
while True:
while start < stop and array[start].isdecimal():
start += 1
while start < stop and array[stop].isdecimal():
stop -= 1
if start >= stop:
break
array[start], array[stop] = array[stop], array[start]
start, stop = start + 1, stop - 1
return ''.join(array)
>>> reverse_non_decimal('abc12de')
'edc12ba'
>>> reverse_non_decimal('abcde79')
'edcba79'
>>> reverse_non_decimal('123ab456')
'123ba456'
>>>
一个人可能会问的问题是“哪个更好?”如果速度是衡量最佳状态的标准,那么您可能会感兴趣以下数字:
>>> import timeit
>>> timeit.timeit('reverse_non_digits("abc123def")',
'from __main__ import reverse_non_digits')
2.7516707000004317
>>> timeit.timeit('reverse_non_decimal("abc123def")',
'from __main__ import reverse_non_decimal')
2.3575149000007514
>>>
将这些结果与Mark Meyer的answer中rev
函数的时间进行比较:
>>> def rev(st):
s = list(st)
i = 0
j = len(s)-1
while i < j:
while (i < len(s) and s[i].isnumeric() ):
i += 1
while (j >=0 and s[j].isnumeric()):
j -= 1
if i < j:
s[j], s[i] = s[i], s[j]
i += 1
j -= 1
return ''.join(s)
>>> timeit.timeit('rev("abc123def")',
'from __main__ import rev')
3.657291699999405
>>>
在这三个函数中,似乎reverse_non_decimal
是最快的。