2013-08-05 1 views
3

Как я могу генерировать последовательные списки, комбинируя любые два элемента из более длинного списка, например, с 4 элементами?Создать списки с любыми двумя элементами из более длинного списка DrRacket

Например, я хочу, чтобы получить '(1 2), '(1 3), '(1 4), '(2 3), '(2 4) и '(3 4) на основе '(1 2 3 4).

ответ

0

Я думаю, что вы хотите все перестановки в соответствии с this answer.

Используя его определение функции перестановки, вы могли бы сделать что-то вроде:

(permutations 2 '(1 2 3 4)) 
+0

В этом случае решение требует комбинаций, а не перестановок входного списка. Точная противоположность ситуации, описанной в связанном ответе –

+0

Вы правы. Я всегда возвращаюсь назад. Давайте посмотрим, смогу ли я исправить пример ... Или вы также можете :-) – Peter

+0

Я уже исправил это, в своем ответе;) –

3

Вопроса требующее для 2 размера списка комбинаций из данного списка. Он может быть реализован с точки зрения более общей процедуры, которая производит п-размерные комбинации:

(define (combinations size elements) 
    (cond [(zero? size) 
     '(())] 
     [(empty? elements) 
     empty] 
     [else 
     (append (map (curry cons (first elements)) 
         (combinations (sub1 size) (rest elements))) 
       (combinations size (rest elements)))])) 

Он работает, как ожидалось, когда мы указываем, что size=2:

(combinations 2 '(1 2 3 4)) 
=> '((1 2) (1 3) (1 4) (2 3) (2 4) (3 4)) 
+0

Это действительно хороший ответ, но я был удивлен, что не нашел его в ракетке, учитывая его присутствие как в Python (itertools), так и в Clojure (math.combinatorics) – Peter

+0

Согласен. Должен существовать стандартный комбинаторный модуль для Racket, используя потоки –

+0

Вы думаете, о чем я думаю? ;-) – Peter

2

Вот решение так же, как вы указали (одна функция, один аргумент). Для ввода типа '(next rest ...) решение вычисляет результат для next, а затем рекурсирует на rest ... - используя append для объединения двух частей.

(define (combine elts) 
    (if (null? elts) 
     '() 
     (let ((next (car elts)) 
      (rest (cdr elts))) 
     (append (map (lambda (other) (list next other)) rest) 
       (combine rest))))) 
> (combine '(1 2 3 4)) 
((1 2) (1 3) (1 4) (2 3) (2 4) (3 4))