Цель: Итак, моя цель — написать рекурсивную функцию is_subsequent, которая по двум строкам возвращает, является ли первая строка следствие второго. НАПРИМЕР, учитывая hac и катарсик, вы должны вернуть true, но учитывая bat и таблица, вы должны вернуть false.
Я попытался написать код, чтобы проверить, является ли одна строка подстрокой другой. Вот мой код:
def is_subsequent(str1, str2):
x = 0
if (all(i in str2 for i in str1)):
x = 1
if (x):
return True
else:
return False
Но он не заботится о порядке строки. Я хочу написать код, учитывающий порядок, указанный в цели. И решить это с помощью РЕКУРСИИ.
Итак, что вы знаете о рекурсии? Вы должны быть в состоянии показать различные цели написания рекурсивной функции и то, что, по вашему мнению, вы можете сделать в коде для их достижения.
Основная идея рекурсии заключается в том, что ваша функция делает две разные вещи:
В случае этой проблемы у вас есть два базовых случая:
True
.False
.Тогда у вас есть два способа упростить задачу (т. е. уменьшить одну или обе строки):
ac
является подпоследовательностью artic
ЕСЛИ c
является подпоследовательностью rtic
.)hac
является подпоследовательностью cathartic
IFF hac
является подпоследовательностью athartic
.)>>> def is_subsequence(needle: str, haystack: str) -> bool:
... if not needle:
... return True
... if not haystack:
... return False
... if needle[0] == haystack[0]:
... return is_subsequence(needle[1:], haystack[1:])
... return is_subsequence(needle, haystack[1:])
...
>>> is_subsequence("hac", "cathartic")
True
>>> is_subsequence("bat", "table")
False
С тем, как вы сформулировали свой вопрос в отношении логики в коде, который вы разместили, кажется, что есть разрыв...
Вы ясно дали понять, что создание рекурсивной функции является обязательным требованием, но если ваша функция использует ключевое слово all
и просто проверяет str1
для всех символов в str2
, это почти нарушило бы логику создания рекурсивной функции.
Вы можете передать дополнительную переменную и удалить символы при каждом последующем рекурсивном вызове с оператором завершения при каждом проходе, который даст вам правильный вывод.
def is_subsequent(search, text):
if len(text) < len(search):
return False
for i, c in enumerate(search):
if c != text[i]:
return is_subsequent(search, text[1:])
return True
Эта функция проверяет, не меньше ли длина строки поиска, чем текстовая строка.
Если это так, проверьте каждый символ строки поиска по очереди, чтобы увидеть, совпадает ли он с текстовой строкой.
Если символ никогда не совпадает, попробуйте функцию еще раз, но с 1 места дальше по тексту.
Это вспомогательные функции, которые имеют дело с тривиальными случаями, такими как пустая подпоследовательность, которая всегда будет возвращать истину, или подпоследовательность больше, чем другая строка, или другая строка пуста, а подпоследовательность нет, что всегда будет возвращать ложь.
def is_subsequent(str1, str2):
if str1 == "":
return True
elif str2 == "" or len(str1) > len(str2):
return False
else:
return _is_subsequent(str1, str2, 0, 0)
Эта функция здесь принимает обе строки и два указателя, которые всегда указывают позицию, в которой вы в настоящее время сравниваете обе строки, в качестве альтернативы вы можете использовать две подстроки и всегда сравнивать их первые символы.
Если какой-либо из указателей достигает индекса, который больше не находится в пределах строки, пришло время выполнить оценку. Если i-указатель достиг конца, мы возвращаем true, если нет, мы возвращаем false.
def _is_subsequent(str1, str2, i, j):
if i >= len(str1) or j >= len(str2):
return i >= len(str1)
if str1[i] == str2[j]:
return _is_subsequent(str1, str2, i + 1, j + 1)
else:
return _is_subsequent(str1, str2, i, j + 1)
Ответит ли этот репозиторий GitHub на ваш вопрос: github.com/netsetos/python_code/blob/master/recur_substring.py?