简体   繁体   English

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

[英]List of Permutations in Racket without using Functions like map and lambda

I am not able to write a helper function which does the same job as map and lambda我无法编写与 map 和 lambda 相同的工作的助手 function

(define (permutations lst)                                                               
       (cond [(empty? lst) '()]                                                               
       [(empty? (rest lst)) (list lst)]                                                         
       [else???]))

map is just an abstractiom. map只是一个抽象。 Imagine you make a typical list eater:想象一下,你做了一个典型的吃名单者:

;; 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))

Do you notice how similar those two are?你注意到这两个有多相似吗? It's almost 90% the same code.几乎 90% 的代码相同。 The common code is the core of map :通用代码是map的核心:

(define (map1 f lst)
  (if (null? lst)
      '()
      (cons (f (car lst))
            (map1 f (cdr lst)))))

Ad now we can implement the two using map1广告现在我们可以使用map1来实现这两者

(define (add2 lst)
  (map1 (lambda (v) (+ v 2)) lst))

(define (revel lst)
  (map1 reverse lst))

Of course map is more than map1 since it also supports more list arguments, but implementing a full map is beyond the scope of this post.当然mapmap1更多,因为它还支持更多列表 arguments,但是实现完整的map超出了此 Z31A1FD14EC14BEF2D18ZE 后的 Z31A1FD140BE4BEF2D58ZE

So here is one approach to doing this.因此,这是执行此操作的一种方法。 I assume you are allowed to write helper functions.我假设您允许编写辅助函数。

The first step is to realise that at some point you are going to need to take a list of elements and 'thread' something through it, producing all the possible new lists with that element inserted somewhere.第一步是要意识到,在某些时候,您将需要获取一个元素列表并通过它“穿线”一些东西,生成所有可能的新列表,并将该元素插入某处。 So given (1 2) and 3 you want to make ((3 1 2) (1 3 2) (1 2 3)) .所以给定(1 2)3你想要((3 1 2) (1 3 2) (1 2 3))

And for reasons which will become clear I'm going to do this in such a way that the function adds its answers to some preexisting ones.出于显而易见的原因,我将以 function其答案添加到一些先前存在的答案的方式来执行此操作。 And it's going to have, itself, a little helper function.它本身将有一个小帮手 function。

(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))))

So let's test this:所以让我们测试一下:

> (thread-list 1 '(2 3) '())
'((2 3 1) (2 1 3) (1 2 3))

Now we want a function which will take an element, and a bunch of lists, and thread the element through each of the lists, accumulating the result:现在我们想要一个 function 它将接受一个元素和一堆列表,并将元素穿过每个列表,累积结果:

(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))))

And checking this:并检查:

> (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))

And I'm going to stop here, but look at what the above call did : given ((2 3) (3 2)) , which is the permutations of (2 3) , and 1 , it returned the permutations of (1 2 3) , So you should now be able to write another function, permutations , which makes use of thread-lists to create permutations.我将在这里停下来,但看看上面的调用做了什么:给定((2 3) (3 2)) ,这是(2 3)的排列,和1 ,它返回了(1 2 3) ,所以您现在应该能够编写另一个函数permutations ,它利用thread-lists来创建排列。


Note I don't know if this approach is anything like efficient and I would expect it not to be.注意我不知道这种方法是否有效,我希望它不会。 It is, I think, fairly clear.我认为这是相当清楚的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM