Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/scheme/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 置换方案码的解释_Scheme_Permutation_Definition - Fatal编程技术网

Scheme 置换方案码的解释

Scheme 置换方案码的解释,scheme,permutation,definition,Scheme,Permutation,Definition,以下是生成元素列表排列的方案代码: (define (remove x lst) (cond ((null? lst) '()) ((= x (car lst)) (remove x (cdr lst))) (else (cons (car lst) (remove x (cdr lst)))))) (define (permute lst) (cond ((= (length lst) 1) (list lst)) (else (

以下是生成元素列表排列的方案代码:

 (define (remove x lst)   (cond
     ((null? lst) '())
     ((= x (car lst)) (remove x (cdr lst)))
     (else (cons (car lst) (remove x (cdr lst))))))

 (define (permute lst)   (cond
     ((= (length lst) 1) (list lst))
     (else (apply append
            (map (lambda (i) 
             (map (lambda (j) (cons i j))
                  (permute (remove i lst)))) lst)))))
如果我们把代码拆开,我确实理解代码的每一部分,但我不理解的是这一切是如何导致产生排列的

假设我们使用列表
(ab)
,它如何生成
(ab)
(ba)


我们首先从列表中删除
a
,并保留
b
,但是哪里写着您现在必须将
a
改为
b
b
是一个单独的元素,但在我对代码的解释中,
b
也将被删除,并且没有留下任何内容……

我将这样阅读主要部分(按照数字指示的顺序)

(应用附加(映射f xs))
==

在等式模式匹配伪代码中重新编写代码

remove x [x, ...ys] = remove x ys           ; skip this x, and go on removing
            ; ( consider skipping just this one occurrence instead:
            ;       = ys                                           )
remove x [y, ...ys] = [y, ...remove x ys]   ;   (or else x /= y, so keep this y)
remove x [] = []                            ; until the list is exhausted

permute [x] = [[x]]
permute xs  = 
    xs                                ; ( with (xs |> f) == (f xs) )
    |> flatmap (x =>                  ; for each x in xs, 
          permute (remove x xs)       ;   for each permutation p of xs w/o x,
          |> map (p => [x, ...p]) )   ;      prepend x to p and 
                                      ;   splice the results in place of x
这更清楚吗

没有?那么,让我们看看如何计算
permute[a,b]

首先,什么是
permute[a]

  permute [a] = ...
( permute [x] = [[x]] )
          ... = [[a]]
(不管我们如何调用单个元素列表的第一个元素,它仍然是它的第一个也是唯一的元素)。同样地

  permute [b] = ...
( permute [x] = [[x]] )
          ... = [[b]]
好的,但是它如何帮助我们看到
置换[a,b]
的结果呢?让我们一步一步地进行:

permute [      a,          b       ] =
   ;; for each x in (xs==[a,b])
   ;;          a           b           ; <<- the value of x
   ;;      remove x from xs
   ;;         [b]         [a]          ; <<- xs with x removed
   ;;      prepend x to each permutation of the above
   ;;       [[  b]]     [[  a]]        ; <<- permutations
   ;;       [[a,b]]     [[b,a]]        ; <<- prefixed with x
   ;;      splice them in by `apply append`
        [    [a,b]   ,   [b,a]     ]
这更清楚吗?

(TL;DR:口头解释在这个答案的最后。)

让我们尝试使用
Let*
-rewrites来遵循这些定义。定义如下:

(define (remove x lst)   (cond
    ((null? lst) '())
    ((= x (car lst)) (remove x (cdr lst)))
    (else (cons (car lst) (remove x (cdr lst))))))

(define (permute lst)   (cond
    ((= (length lst) 1) (list lst))
    (else (apply append
           (map (lambda (i) 
            (map (lambda (j) (cons i j))
                 (permute (remove i lst)))) lst)))))
我们尝试

(permute '(a b))
≡
(let* ((lst '(a b)))
  (apply append
     (map (lambda (i)
             (map (lambda (j) (cons i j))
                  (permute (remove i lst))))
          lst)))
≡
(let* ((lst '(a b))
       (r  (map (lambda (i)
                  (map (lambda (j) (cons i j))
                       (permute (remove i lst))))
                lst)))
  (apply append r))
≡
(let* ((lst '(a b))
       (i1 'a)
       (r1 (map (lambda (j) (cons i1 j))
                       (permute (remove i1 lst))))
       (i2 'b)
       (r2 (map (lambda (j) (cons i2 j))
                       (permute (remove i2 lst))))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((lst '(a b))
       (i1 'a)
       (t1 (permute (remove i1 lst)))
       (r1 (map (lambda (j) (cons i1 j)) t1))
       (i2 'b)
       (t2 (permute (remove i2 lst)))
       (r2 (map (lambda (j) (cons i2 j)) t2))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((i1 'a)
       (t1 (permute '(b)))
       (r1 (map (lambda (j) (cons i1 j)) t1))
       (i2 'b)
       (t2 (permute '(a)))
       (r2 (map (lambda (j) (cons i2 j)) t2))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((i1 'a)
       (t1 '( (b) ))
       (r1 (map (lambda (j) (cons i1 j)) t1))
       (i2 'b)
       (t2 '( (a) ))
       (r2 (map (lambda (j) (cons i2 j)) t2))
       (r (list r1 r2)))
  (apply append r))
(置换(a-b))
≡
(让*((lst’(a b)))
(应用附加)
(地图(lambda(i)
(地图(lambda(j)(cons i j))
(置换(移除i lst)))
(lst)
≡
(让*((lst’(a和b))
(r)地图(lambda(i)
(地图(lambda(j)(cons i j))
(置换(移除i lst)))
(lst)
(适用于附录r)
≡
(让*((lst’(a和b))
(i1'a)
(r1(map(lambda(j)(cons i1 j))
(置换(移除i1 lst)))
(i2’b)
(r2(map(lambda(j)(cons i2 j))
(置换(移除i2 lst)))
(r(列表r1和r2)))
(适用于附录r)
≡
(让*((lst’(a和b))
(i1'a)
(t1(置换(移除i1 lst)))
(r1(map(lambda(j)(cons i1 j))t1))
(i2’b)
(t2(置换(移除i2 lst)))
(r2(map(lambda(j)(cons i2 j))t2))
(r(列表r1和r2)))
(适用于附录r)
≡
(让*((i1’a)
(t1(排列’(b)))
(r1(map(lambda(j)(cons i1 j))t1))
(i2’b)
(t2(排列’(a)))
(r2(map(lambda(j)(cons i2 j))t2))
(r(列表r1和r2)))
(适用于附录r)
≡
(让*((i1’a)
(t1’((b)))
(r1(map(lambda(j)(cons i1 j))t1))
(i2’b)
(t2’((a)))
(r2(map(lambda(j)(cons i2 j))t2))
(r(列表r1和r2)))
(应用append r))
所以我们得到了

(let* ((r1 (map (lambda (j) (cons 'a j)) '( (b) )))
       (r2 (map (lambda (j) (cons 'b j)) '( (a) )))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((r1 (list (cons 'a '(b))))
       (r2 (list (cons 'b '(a))))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((r1 (list '(a b)))
       (r2 (list '(b a)))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((r1  '((a b)))
       (r2  '((b a)))
       (r (list r1 r2)))
  (apply append r))
≡
(apply append (list '((a b)) '((b a))))
≡
(      append       '((a b)) '((b a)) )
≡
'(                    (a b)    (b a)  )
(let*((r1(map)(lambda(j)(cons'aj)))((b)))
(r2)(map(lambda(j))(cons"b j)(a))
(r(列表r1和r2)))
(适用于附录r)
≡
(让*((r1(列表a(b)))
(r2(列表(反对‘b’(a)))
(r(列表r1和r2)))
(适用于附录r)
≡
(让*((r1(列表)(a和b)))
(r2(列表(b a)))
(r(列表r1和r2)))
(适用于附录r)
≡
(让*((r1’((a b)))
(r2’((b a)))
(r(列表r1和r2)))
(适用于附录r)
≡
(应用附加(列表“((a b))”((b a)))
≡
(附加“((a b))”((b a)))
≡
“((a b)(b a))
如果您需要说服自己中间结果的有效性,请遵循相同的技巧


事后看来,我们可以更积极地简化它,比如

(let* ((lst '(a b))
       (i1 'a)
       (r1 (map (lambda (j) (cons i1 j))
                       (permute (remove i1 lst))))
       (i2 'b)
       (r2 (map (lambda (j) (cons i2 j))
                       (permute (remove i2 lst))))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((lst '(a b))
       (i1 'a)
       (t1 (permute (remove i1 lst)))
       (r1 (map (lambda (j) (cons i1 j)) t1))
       (i2 'b)
       (t2 (permute (remove i2 lst)))
       (r2 (map (lambda (j) (cons i2 j)) t2)))
  (apply append (list r1 r2)))
≡
(let* ((t1 (permute '(b)))
       (r1 (map (lambda (j) (cons 'a j)) t1))
       (t2 (permute '(a)))
       (r2 (map (lambda (j) (cons 'b j)) t2)))
  (append r1 r2))
≡
(let* ((r1 (map (lambda (j) (cons 'a j)) '( (b) )))
       (r2 (map (lambda (j) (cons 'b j)) '( (a) )))
       )
  (append r1        ; one row for each elt            '( a
          r2        ;  of the input list,                b
          ))        ;  spliced in place by append        )
(let*((lst'(a b))
(i1'a)
(r1(map(lambda(j)(cons i1 j))
(置换(移除i1 lst)))
(i2’b)
(r2(map(lambda(j)(cons i2 j))
(置换(移除i2 lst)))
(r(列表r1和r2)))
(适用于附录r)
≡
(让*((lst’(a和b))
(i1'a)
(t1(置换(移除i1 lst)))
(r1(map(lambda(j)(cons i1 j))t1))
(i2’b)
(t2(置换(移除i2 lst)))
(r2(map(lambda(j)(consi2j))t2)))
(应用附加(列表r1 r2)))
≡
(let*((t1(置换)(b)))
(r1(map(lambda(j)(cons'a j))t1))
(t2(排列’(a)))
(r2(图(λ(j)(cons'b j))t2)))
(附r1(r2))
≡
(让*((r1(map)(lambda(j)(cons'aj))”((b)))
(r2)(map(lambda(j))(cons"b j)(a))
)
(附加r1;每行一行)
r2;输入列表的
));通过附加在适当位置拼接)
最后,以更直观的方式揭示计算结构:

  • 对于输入列表的每个元素,
    • 找到余数的所有排列
    • 在每个元素前面加上该元素
  • 并通过将所有这些结果附加在一起,将处理输入列表中每个元素的结果连接在一起

(因此,我的另一个基于此处的伪代码是合理的)。

理解代码的第一步是将其格式化以供人类使用。把它分成几行,适当缩进。你无法阅读这个长方形的东西,我们也一样。有几个编辑器对scheme(vim,emacs,…)具有完全合理的自动缩进功能。@dratenik这只是他们的一部分错误,但主要是一个错误。在进行了一些小的修改之后,剩下的是一些特殊的东西,是的,但仍然是一种可读性很强的格式。获取相关的见解
(apply append(map f xs))
=
(flatmap f xs)
@alinsoar OP已经提供了一个定义,一般来说,他们不会问如何实现它。它在列表中,而在数组中,它可以完全不同。所以我不明白你删除了这两个标签。@alinsoar这个具体的问题
(let* ((r1 (map (lambda (j) (cons 'a j)) '( (b) )))
       (r2 (map (lambda (j) (cons 'b j)) '( (a) )))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((r1 (list (cons 'a '(b))))
       (r2 (list (cons 'b '(a))))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((r1 (list '(a b)))
       (r2 (list '(b a)))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((r1  '((a b)))
       (r2  '((b a)))
       (r (list r1 r2)))
  (apply append r))
≡
(apply append (list '((a b)) '((b a))))
≡
(      append       '((a b)) '((b a)) )
≡
'(                    (a b)    (b a)  )
(let* ((lst '(a b))
       (i1 'a)
       (r1 (map (lambda (j) (cons i1 j))
                       (permute (remove i1 lst))))
       (i2 'b)
       (r2 (map (lambda (j) (cons i2 j))
                       (permute (remove i2 lst))))
       (r (list r1 r2)))
  (apply append r))
≡
(let* ((lst '(a b))
       (i1 'a)
       (t1 (permute (remove i1 lst)))
       (r1 (map (lambda (j) (cons i1 j)) t1))
       (i2 'b)
       (t2 (permute (remove i2 lst)))
       (r2 (map (lambda (j) (cons i2 j)) t2)))
  (apply append (list r1 r2)))
≡
(let* ((t1 (permute '(b)))
       (r1 (map (lambda (j) (cons 'a j)) t1))
       (t2 (permute '(a)))
       (r2 (map (lambda (j) (cons 'b j)) t2)))
  (append r1 r2))
≡
(let* ((r1 (map (lambda (j) (cons 'a j)) '( (b) )))
       (r2 (map (lambda (j) (cons 'b j)) '( (a) )))
       )
  (append r1        ; one row for each elt            '( a
          r2        ;  of the input list,                b
          ))        ;  spliced in place by append        )