Опрос по рекурсии - не удалось решить
Сегодня мой профессор CPSC назначил викторину в python, тема была рекурсией.
Весь класс застрял на вопросе номер два, который ниже. Никто не смог даже приблизиться к решению.
def sub_set(A):
if A == []: return A
X = sub_set(A[1:])
result = []
for L in X:
result += _____
return _____
Пример кода:
print(sub_set([1, 2])) # [[], [1], [2], [1, 2]]
print(sub_set([1, 2, 3])) # [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
Вам разрешено изменять символы подчеркивания, например, мой пример ниже.
Мое решение было настолько далеким от закрытия, что его даже не следует рассматривать:
def sub_set(A):
if A == []: return A
X = sub_set(A[1:])
result = []
for L in X:
result += _____
return result + [A[:1]] + [A] + [A[::2]]
#sub_set([1, 2, 3]) -> [[3], [3], [3], [2], [2, 3], [2], [1], [1, 2, 3], [1, 3]]
Кто-нибудь знает, как это можно решить? Это кажется довольно сложной проблемой, когда у нас есть только 15 минут, чтобы решить эту проблему.
Просто для справки, он сказал, что бросит вопрос, не рассматривая никого в классе - продвинутый класс comp sci примерно из 10 тщательно отобранных студентов - мог бы его решить.
Ответы
Ответ 1
Я думаю, что есть ошибка в вопросе. Базовый регистр для рекурсии неверен.
Множество всех подмножеств пустого множества - это не пустое множество, а множество, содержащее пустое множество.
def sub_set(A):
if A == []: return A
должен быть
def sub_set(A):
if A == []: return [A]
Добавлено: С этим патчем, здесь решение:
def sub_set(A):
if A == []: return [A]
X = sub_set(A[1:])
result = []
for L in X:
result += [L, A[0:1] + L]
return result
Ответ 2
Я не считаю, что это разрешимо без какого-либо серьезного хакера, потому что базовый случай ошибочен. Для []
должно быть одно подмножество: []
. Но return A
не возвращает никаких подмножеств.
Итак, вместо того, чтобы просто делать A[:1] + L
, вам нужно сделать [A[:1] + L]
. И вместо A[:1] + X + result
вам нужно сделать [A[:1]] + X + result
. Итак:
def sub_set(A):
if A == []: return A
X = sub_set(A[1:])
result = []
for L in X:
result += [A[:1] + L]
return [A[:1]] + X + result
Это все равно оставляет пустой список из подмножеств. И единственный способ исправить это - что-то глупое:
return ([] if [] in X + result else [[]]) + [A[:1]] + X + result
Это, по крайней мере, вернет правильные значения... но в неправильном порядке и с дубликатами всех одноэлементных подмножеств. Вы можете расширить хакерство, если хотите; Я не думаю, что это того стоит.
Ответ 3
def sub_set(A):
if A == []: return A
X = sub_set(A[1:])
result = []
for L in X:
result += [L, [A[0]]+L]
return [[A[0]]] + result
print sub_set([1, 2])
>> [[1], [2], [1, 2]]
print sub_set([1, 2, 3])
>> [[1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
Ответ 4
def sub_set(A):
if A == []: return A
X = sub_set(A[1:])
result = []
for L in X:
result += [L, A[0:1] + L]
return result if X != [] else [[], A[0:1]]
Это по существу то же самое, что и noa, минус изменение части кода, который вы не должны редактировать.
Ответ 5
X
- это набор всех подмножеств, которые НЕ включают A[0]
. Это означает, что они также находятся в subset(A)
. Отсутствие всех подмножеств, содержащих DO A[0]
, которые вы можете получить, добавив A[0]
к каждому из элементов в X
.
Итак, ваш первый пробел будет A[0] + L
И ваш второй будет result + X
Ответ 6
Не решение, которое вы ищете, но здесь работает решение с использованием yield:)
def powerset(A):
if A:
for L in powerset(A[1:]):
yield L
yield A[:1] + L
else:
yield []
Ответ 7
это возможное решение. он возвращает правильные значения, но не обязательно в том же порядке:
def sub_set(A):
if A == []: return A
X = sub_set(A[1:])
result = []
for L in X:
result += [ A[:1] +L ]
return [[]] + X[1:] + (result or [A[:1]])
Эффективно, что это делает, для каждого слоя мы разбиваем исходный список на две части: начальный элемент и остальную часть списка. Мы получаем все подмножества остальной части списка, добавляем первый элемент к каждой части, добавляем [] и возвращаем его.
Пример потока:
[1,2,3] -> A0 = [1], A1X =[2,3] ->
[2,3] -> A0 = [2], A1X = [3] ->
[3] -> A0 = [3], A1X = [] ->
[] -> return []
[3] * [] = []. return [ [], [3] ]
[2] * [[], [3]] = [[2], [2,3]]. return [ [] + [[3]] + [[2], [2,3]] ]
[1] * [ [], [3], [2], [2,3] ] = [[1], [1,3], [1,2], [1, 2, 3] ]
return [ [] + [[], [3], [2], [2,3]] + [[1], [1,3], [1,2], [1,2,3]]
Общий поток [] + A0 * [подмножество] + [подмножество]. Вопросы, которые нужно посмотреть, это то, что подмножество всегда начинается с [] - поэтому вы получите его дважды, если вы его не удалите, и убедитесь, что вы не дублируете A0, когда он уже существует (в качестве [A0] + [] == [A0], и у вас всегда есть [A0] в списке), но на самой первой итерации (после возвращения []) вам нужно специально включить его.