反向字符串,但不是整数

时间:2019-05-24 17:35:54

标签: python-3.x

面试问题:反转字符串,但仅反转字母字符。整数应保持其原始位置。

输入:“ 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"))

3 个答案:

答案 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
  1. 浏览字符串中的字符,检查它们是否为字母。
  2. 如果为true,则将它们添加到新的输出字符串中,否则添加字符和 其位置(作为元组)到数字字符列表的位置。
  3. 反转仅字母字符串。
  4. 遍历数字列表,并将其插入到新字符串中的原始位置。

测试

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 Meyerapproach

>>> 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 Meyeranswerrev函数的时间进行比较:

>>> 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是最快的。