Допустим, у нас есть следующая последовательность:
[1, 2, 1, 1]
Мы хотим вычислить все подпоследовательности из данной последовательности в соответствии со следующим правилом:
if s_i <= s_i+1 then s_i+1 is part of a subsequence with s_i
Подпоследовательность вычисляетсяначиная с первого элемента последовательности, здесь 1
, и сравнивая его с его правым соседом, здесь 2
.Если они применяются к условию, то образуют подпоследовательность.После этого 2
необходимо сравнить с его правым соседом 1
, и, если они применяются, он присоединяется к подпоследовательности.Здесь они этого не делают, поэтому он не присоединяется.
Этот процесс продолжается с 2
и соседом предыдущего соседа 1
до конца последовательности.После этого процесс продолжается с соседом 2
аналогичным образом.
На следующем графике показан процесс построения подпоследовательности для первого элемента 1
в последовательности:
Следовательно, проблема носит рекурсивный характер.Вот код:
def calc(seq):
for i in range(0, len(seq)):
calc_subseq(i, seq)
def calc_subseq(i, seq):
a = seq[i]
for j in range(i+1, len(seq):
b[j] = seq[j]
if b <= a:
calc_subseq(j, seq);
else:
#build subsequence
#build subsequnce
Вопрос теперь:
Как получить подпоследовательности после их вычисления?Я использовал стек и передавал его при каждом вызове.Кроме того, я передал счетчик, который увеличивается с каждым совпадением и передается при каждом вызове функции, а также возвращается впоследствии.В случае несоответствия я выбрасываю из стека столько предметов, сколько считает счетчик.Я делаю то же самое, когда конец цикла for достигается в calc_subseq(seq)
.Но я ищу лучшее решение.
Кто-нибудь знает какой-либо алгоритм для решения подобных проблем?Было бы довольно интересно, если бы был более эффективный способ.Я думал о каком-то динамическом программировании.
Редактировать:
В соответствии с запросом, здесь приведены все результаты для входной последовательности [1,2,1,1]
:
1 (0), 2 (1)
2 (1)
2 (1)
2 (1) -> end
1 (0), 1 (2), 1 (3)
1 (3) -> end
1 (2) -> end
1 (0), 1(3)
1 (3) -> end
1 (0) -> end
2 (1)
2 (1)
2 (1) -> end
1 (2), 1 (3)
1 (3) -> end
1 (2) -> end
1 (3) -> end
Примечание: Индексы представлены как (x)
.-> end
указывает, что был достигнут конец второго цикла for.Следовательно, он показывает последний элемент, который нельзя сравнить, потому что не осталось соседа.