Загадка StarKill в Python - PullRequest
       0

Загадка StarKill в Python

0 голосов
/ 06 февраля 2020

Загадка:

Возвращает версию данной строки, где для каждой звезды (*) в строке пропадают звезда и символы непосредственно слева и справа. Таким образом, "ab * cd" выдает "ad", а "ab ** cd" также выдает "ad".

Мне интересно, есть ли способ pythoni sh, чтобы улучшить это алгоритм:

def starKill(string): 

    result = ''

    for idx in range(len(string)):

        if(idx == 0 and string[idx] != '*'):
            result += string[idx]
        elif (idx > 0 and string[idx] != '*' and (string[idx-1]) != '*'):
            result += string[idx]
        elif (idx > 0 and string[idx] == '*' and (string[idx-1]) != '*'):
            result = result[0:len(result) - 1]

    return result

starKill ("wacy * xko") выход wacko

Ответы [ 4 ]

1 голос
/ 06 февраля 2020

Регулярное выражение?

>>> import re
>>> for s in "ab*cd", "ab**cd", "wacy*xko", "*Mad*Physicist*":
        print(re.sub(r'\w?\*\w?', '', s))

ad
ad
wacko
ahysicis
1 голос
/ 06 февраля 2020

Вот решение numpy просто для удовольствия:

def star_kill(string, target='*'):
    arr = np.array(list(string))
    mask = arr != '*'
    mask[1:] &= mask[:-1]
    mask[:-1] &= mask[1:]
    arr = arr[mask]
    return arr[mask].view(dtype=f'U{arr.size}').item()
0 голосов
/ 06 февраля 2020

Вы можете сделать это, перебирая строку три раза параллельно. Каждая итерация будет сдвинута относительно следующей на один символ. Средний - тот, который будет предоставлять действительные буквы, два других позволяют нам проверять, являются ли соседние символы звездами. Два фланкирующих итератора требуют, чтобы фиктивные значения представляли «до начала» и «после конца» строки. Есть множество способов установить это, я использую itertools.chain.islice), чтобы заполнить None для фиктивных значений. Но вы можете использовать обычные операции с строками и итераторами (например, iter('x' + string) и iter(string[1:] + 'x')):

import itertools

def star_kill(string):
    main_iterator = iter(string)
    look_behind = itertools.chain([None], string)
    look_ahead = itertools.chain(itertools.islice(string, 1, None), [None])

    return "".join(a for a, b, c in zip(main_iterator, look_behind, look_ahead)
                     if a != '*' and b != '*' and c != '*')
0 голосов
/ 06 февраля 2020

Не уверен, действительно ли это "Pythoni c", но проблему можно решить с помощью регулярных выражений.

import re

def starkill(s):
  s = re.sub(".{0,1}\\*{1,}.{0,1}", "", s)
  return s

Для тех, кто не знаком с регулярным выражением, я сломаю эту длинную строку вниз :

Префикс

".{0,1}"

Указывает, что мы хотим, чтобы замещаемый раздел начинался с 0 или 1 любого символа. Если перед звездой есть персонаж, мы хотим заменить его; в противном случае мы все еще хотим, чтобы выражение попадало, если звезда находится в самом начале входной строки.

Звезда

"\\*{1,}"

Это указывает, что середина выражение должно содержать символ звездочки, но также может содержать более одного. Например, «*****» все равно будет попадать, даже если есть четыре звезды. Нам нужна обратная косая черта sh перед звездочкой, потому что регулярное выражение имеет звездочку в качестве зарезервированного символа, и нам нужна вторая обратная косая черта sh перед , которая , поскольку строки Python резервируют символ обратной косой черты sh.

Суффикс

.{0,1}

То же, что и префикс. Выражение может заканчиваться одним или нулем любого символа.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...