Рекурсивная перестановка слов в предложении

1

Я хочу, чтобы recursively получить перестановки слов в предложении, сохраняя смежные слова в пакетах из двух, вместе слева направо.

Так, например, если я рассматриваю a, B, c, D - 4 слова, а главное предложение имеет 5 вхождений из 4 слов:

основное предложение: a + B + c + a + D

Я бы получил четыре предложения:

c + a + B + c + a
a + B + c + a + D
a + B + c + a + B
B + c + a + B + c

которые имеют ту же длину, что и основное предложение, и следует отметить, что последнее слово в главном предложении, т.е. D приходит только один раз и только в конце предложения после a потому что в главном предложении слова не следует.

  • 0
    Вы упоминаете, что хотите рекурсивное решение, а затем упоминаете нерекурсивное решение. Какой метод вы используете?
  • 0
    Я удалю второй - давайте решим это рекурсивно :)
Показать ещё 2 комментария
Теги:
permutation
recursion
sentence

2 ответа

1
Лучший ответ

Вы можете использовать следующую функцию рекурсивного генератора:

def adjacent_combinations(sentence, target=None, length=0):
    if not target:
        for target in set(sentence):
            for combination in adjacent_combinations(sentence, target, 1):
                yield combination
    elif length == len(sentence):
        yield [target]
    else:
        for a, b in set(zip(sentence, sentence[1:])):
            if a == target:
                for combination in adjacent_combinations(sentence, b, length + 1):
                    yield [a] + combination

чтобы:

list(adjacent_combinations(['a', 'B', 'c', 'a', 'D']))

вернется:

[['B', 'c', 'a', 'B', 'c'],
 ['c', 'a', 'B', 'c', 'a'],
 ['a', 'B', 'c', 'a', 'B'],
 ['a', 'B', 'c', 'a', 'D']]
  • 0
    дает ошибку, что максимальная глубина рекурсии превышена в сравнении, также выход из не работает в питоне <3.3
  • 0
    К сожалению, я сделал опечатку. Я также обновил свой ответ, чтобы не использовать yield from . Пожалуйста, попробуйте еще раз сейчас.
Показать ещё 4 комментария
1

Вы можете использовать генератор с рекурсией:

s = ['a', 'B', 'c', 'a', 'D']
def combinations(d, _c = []):
  if len(_c) == len(d)+1:
     yield _c
  else:
     for i in d:
       if not _c or any(s[c] == _c[-1] and s[c+1] == i for c in range(len(s)-1)):
          for k in combinations(d, _c+[i]):
            yield k

print('\n'.join(' + '.join(i) for i in combinations(set(s))))

Выход:

a + B + c + a + B
a + B + c + a + D
B + c + a + B + c
c + a + B + c + a
  • 0
    умный, но вывод неправильный, если вы обратите внимание на то, что я написал выше, только слова, которые находятся рядом друг с другом слева направо, могут быть вместе, например, в вашем выводе 'c', 'a' не допускается, так как в с 'с' никогда не следует 'а', а также вывод должен быть той же длины, что и основное предложение, то есть 4 в вашем с
  • 0
    @Soyol В каждой последовательности желаемого результата количество букв равно пяти. Кроме того, за «c» следует «a» в B + c + a + B + c как указано в вашем вопросе. Вы можете уточнить?
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню