Functional programming m-集的n-元组生成算法

Functional programming m-集的n-元组生成算法,functional-programming,tuples,racket,permutation,Functional Programming,Tuples,Racket,Permutation,我试图在Racket中实现一个算法(不使用循环),生成元组,该元组消耗长度为m和自然数n的列表,并生成该列表中m个元素集的所有可能的n元组。例如: (check-expect (generate-tuples '(+ -) 3) '((+ + +) (+ + -) (+ - +) (+ - -) (- + +) (- + -) (- - +) (- - -))) 我很难想出一个实用的解决方案。我已经实现了一个算法,可以生成给定m集的所有可能置换: (define (

我试图在Racket中实现一个算法(不使用循环),生成元组,该元组消耗长度为m和自然数n的列表,并生成该列表中m个元素集的所有可能的n元组。例如:

(check-expect
    (generate-tuples '(+ -) 3)
    '((+ + +) (+ + -) (+ - +) (+ - -)
    (- + +) (- + -) (- - +) (- - -)))
我很难想出一个实用的解决方案。我已经实现了一个算法,可以生成给定m集的所有可能置换:

  (define (generate-permutations lst)
  (cond [(empty? lst) empty]
        [(empty? (rest lst)) (list lst)]
        [else
         (local [(define (split left mid right)
                   (append
                    (map (lambda (x) (cons mid x))
                         (generate-permutations (append left right)))
                    (cond [(empty? right) empty]
                          [else (split (cons mid left)
                                       (first right) (rest right))])))]
           (split empty (first lst) (rest lst)))]))  
这是可行的,但我不知道我是否应该尝试在生成元组的解决方案中使用它。我还提出了一个helper函数,它只处理“普通情况”(用于生成元组),即对于列表“(++/)和自然数3,它将生成“(+++)、”(-)和“(//”):


总的来说,元组是有序的,列表长度取决于n,这一事实最让我感到不舒服

以下是一个可能的解决方案:

(define (append-all lst lst-of-lst)
  (if (empty? lst)
      '()
      (append (map (lambda (l) (cons (car lst) l)) lst-of-lst)
              (append-all (cdr lst) lst-of-lst))))

(define (generate-tuples lst n)
  (cond ((= n 0) '())
        ((= n 1) (map list lst))
        (else (let ((tuples (generate-tuples lst (- n 1))))
                (append-all lst tuples)))))

(generate-tuples '(+ -) 3)

'((+ + +) (+ + -) (+ - +) (+ - -) (- + +) (- + -) (- - +) (- - -))
函数
append all
获取一个列表和一个列表列表,依次将第一个列表的每个元素与第二个参数的所有列表连接起来,并返回结果列表


对于n=0,第二个函数的终端情况是空列表,对于n=1,是由包含第一个参数元素的单例列表构成的列表。当它递归时,首先生成包含n-1个元素的结果,然后通过调用append all依次在所有这些列表的开头连接第一个参数的所有元素。

下面是一个可能的解决方案:

(define (append-all lst lst-of-lst)
  (if (empty? lst)
      '()
      (append (map (lambda (l) (cons (car lst) l)) lst-of-lst)
              (append-all (cdr lst) lst-of-lst))))

(define (generate-tuples lst n)
  (cond ((= n 0) '())
        ((= n 1) (map list lst))
        (else (let ((tuples (generate-tuples lst (- n 1))))
                (append-all lst tuples)))))

(generate-tuples '(+ -) 3)

'((+ + +) (+ + -) (+ - +) (+ - -) (- + +) (- + -) (- - +) (- - -))
函数
append all
获取一个列表和一个列表列表,依次将第一个列表的每个元素与第二个参数的所有列表连接起来,并返回结果列表


对于n=0,第二个函数的终端情况是空列表,对于n=1,是由包含第一个参数元素的单例列表构成的列表。当它递归时,首先它生成包含n-1个元素的结果,然后在所有这些列表的开头连接第一个参数的所有元素,依次调用append all。

我知道您想自己编写代码,但为了完整起见,已经这样做了。我知道您想自己编写代码,但为了完整起见,我们已经这么做了。