不使用map和lambda等函数的Racket中的置换列表

不使用map和lambda等函数的Racket中的置换列表,lambda,scheme,racket,permutation,Lambda,Scheme,Racket,Permutation,我无法编写与map和lambda做相同工作的helper函数 定义置换lst cond[空?lst'] [空?剩余lst列表lst] [还有其他吗??] 地图只是一个抽象概念。假设你做了一个典型的列表食客: ;; add 2 to each element (define (add2 lst) (if (null? lst) '() (cons (+ 2 (car lst)) (add2 (cdr lst))))) (add2 '(1 2 3

我无法编写与map和lambda做相同工作的helper函数

定义置换lst cond[空?lst'] [空?剩余lst列表lst] [还有其他吗??] 地图只是一个抽象概念。假设你做了一个典型的列表食客:

;; add 2 to each element
(define (add2 lst)
  (if (null? lst)
      '()
      (cons (+ 2 (car lst))
            (add2 (cdr lst)))))

(add2 '(1 2 3)) ; ==> (3 4 5)

;; reverse each sublist in a list
(define (revel lst)
  (if (null? lst)
      '()
      (cons (reverse (car lst))
            (revel (cdr lst)))))

(revel '((1 2) (3 4))) ; ==> ((2 1) (4 3))
你注意到这两者有多相似吗?几乎90%都是相同的代码。通用代码是map的核心:

现在我们可以使用map1实现这两个


当然,map比map1更重要,因为它还支持更多的列表参数,但是实现完整的map超出了本文的范围。

因此,这里有一种方法可以实现这一点。我假设您可以编写助手函数

第一步是要意识到,在某个时刻,你需要获取一个元素列表,并在其中“穿插”一些东西,生成所有可能的新列表,并将该元素插入其中。所以,给定12和3,你要做31123123

原因很清楚,我将这样做,函数将其答案添加到一些先前存在的答案中。它本身就有一个辅助函数

(define (thread-list e l into)
  ;; Thread e through l accumulating into into
  (thread-list-loop e '() l into))

(define (thread-list-loop e before after into)
  ;; Do the work of threading e through a list:
  ;; - before is the chunk of list before e;
  ;; - after is the chunk after e;
  ;; - into is what we're collecting into
  (if (null? after)
      ;; We now just need before with e at the end
      (cons (append before (list e)) into)
      ;; add the current thing to results and loop
      (thread-list-loop
       e
       (append before (list (first after)))
       (rest after)
       (cons (append before (list e) after) into))))
让我们测试一下:

> (thread-list 1 '(2 3) '())
'((2 3 1) (2 1 3) (1 2 3))
现在我们需要一个函数,它将获取一个元素和一组列表,并将元素穿行于每个列表中,累积结果:

(define (thread-lists e lists into)
  ;; thread e through each element of lists, accumulating into into
  (if (null? lists)
      into
      (thread-lists
       e
       (rest lists)
       (thread-list e (first lists) into))))
检查一下:

> (thread-lists 1 '((2 3) (3 2)) '())
'((3 2 1) (3 1 2) (1 3 2) (2 3 1) (2 1 3) (1 2 3))
我将在这里停止,但看看上面的调用做了什么:给定23,这是23和1的排列,它返回了13的排列!因此,您现在应该能够编写另一个函数,permutations,它利用线程列表来创建置换


注意:我不知道这种方法是否有效,我希望不会。我认为这是相当清楚的。

我想你也不能使用置换或在置换中?是的,没错,我只能使用较低阶的函数,如append、cons、first、rest、reverse和其他一些函数。我不能使用lambda,map,for,permutationssee,如果我有帮助的话。它适用于最多3个元素。对于3以上的元素,你有什么建议吗。如果你有x的排列,比如px,线程列表e px'是e的排列。x、 啊,好的。谢谢
(define (thread-lists e lists into)
  ;; thread e through each element of lists, accumulating into into
  (if (null? lists)
      into
      (thread-lists
       e
       (rest lists)
       (thread-list e (first lists) into))))
> (thread-lists 1 '((2 3) (3 2)) '())
'((3 2 1) (3 1 2) (1 3 2) (2 3 1) (2 1 3) (1 2 3))