Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.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
Functional programming 如何正确计算Scheme中的成对差异?_Functional Programming_Scheme - Fatal编程技术网

Functional programming 如何正确计算Scheme中的成对差异?

Functional programming 如何正确计算Scheme中的成对差异?,functional-programming,scheme,Functional Programming,Scheme,给定一个数字列表,比如说,(13 6 10 0),如果x-1=0,如何计算差异(xi-xi-1) (本例中的结果应为(1234-10)) 我发现这个解决方案是正确的: (define (pairwise-2 f init l) (first (foldl (λ (x acc-data) (let ([result-list (first acc-data)] [prev-x (second acc-data)]) (list

给定一个数字列表,比如说,
(13 6 10 0)
,如果x-1=0,如何计算差异(xi-xi-1)

(本例中的结果应为
(1234-10)

我发现这个解决方案是正确的:

(define (pairwise-2 f init l) (first (foldl (λ (x acc-data) (let ([result-list (first acc-data)] [prev-x (second acc-data)]) (list (append result-list (list(f x prev-x))) x))) (list empty 0) l))) (pairwise-2 - 0 '(1 3 6 10 0)) ;; => (1 2 3 4 -10) (定义(成对-2 f初始l) (一) (福尔德尔) (λ(x acc数据) (let([结果列表(第一个acc数据)] [prev-x(第二次acc数据)]) (名单 (追加结果列表(列表(f x prev-x))) x) )) (列表为空0) l) )) (成对-2-0'(1 3 6 10 0)) ;; => (1 2 3 4 -10) 然而,我认为应该有更优雅但同样灵活的解决方案。真难看

我是函数式编程新手,希望听到关于代码的任何建议


谢谢。

我已经有好几年没做过这个计划了,但这给我的印象是一个典型的小lisper型问题

我从一个基本定义开始(请忽略parens的错位-我手边没有Scheme解释器:

(define pairwise-diff
    (lambda (list)
      (cond
       ((null? list) '())
       ((atom? list) list)
       (t (pairwise-helper 0 list)))))
这将处理null和atom的垃圾案例,然后将肉食案例委托给助手:

(define pairwise-helper
    (lambda (n list)
       (cond
         ((null? list) '())
         (t
            (let ([one (car list)])
               (cons (- one n) (pairwise-helper one (cdr list))))
         ))))
你可以用“if”重写这个,但我用cond

这里有两种情况:空列表-这很简单,其他一切都很简单。
对于其他方面,我抓住了列表的开头,将这个差异转化为递归情况。我认为它不会变得简单。

在改进和适应PLT方案后,我认为近乎完美的解决方案是:

(define (pairwise-apply f l0 l) (if (empty? l) '() (let ([l1 (first l)]) (cons (f l1 l0) (pairwise-apply f l1 (rest l)))))) (定义(成对应用于l0 l) (如果(空?l) '() (让([l1(第一个l)]) (反对意见(f l1 l0)(成对适用于f l1(其余l()()())))
map
接受多个参数。所以我只需要这样做

(define (butlast l)
  (reverse (cdr (reverse l))))
(let ((l '(0 1 3 6 10)))
  (map - l (cons 0 (butlast l)))
如果你想把它包装成一个函数,比如

(define (pairwise-call f init l)
  (map f l (cons init (butlast l))))

这当然不是小阴谋家的方式,而是避免自己编写递归的方式。选择你最喜欢的方式。

Haskell告诉我使用
zip
;)


不管怎样,映射不是在最短参数列表用尽后立即完成吗

(define (pairwise-call fun init-element lst) (map fun lst (cons init-element lst)))
(免责声明:快速破解,未经测试)

这是最简单的方法:

(define (solution ls)
  (let loop ((ls (cons 0 ls)))
    (let ((x (cadr ls)) (x_1 (car ls)))
      (if (null? (cddr ls)) (list (- x x_1))
          (cons (- x x_1) (loop (cdr ls)))))))

(display (equal? (solution '(1)) '(1))) (newline)
(display (equal? (solution '(1 5)) '(1 4))) (newline)
(display (equal? (solution '(1 3 6 10 0)) '(1 2 3 4 -10))) (newline)
写出每个示例的代码扩展,看看它是如何工作的


如果您对开始使用FP感兴趣,请务必查看如何设计程序。当然,它是为编程新手编写的,但里面有很多好的FP习惯用法。

mzscheme给了我“映射:所有列表必须具有相同的大小”。不能将列表用作变量,因为Scheme是Lisp-1。令人惊讶的是,如果删除((atom?LIST)LIST),代码会工作只要不需要调用名为“list”的函数,“list as variable”就可以正常工作。阴影会发生——要习惯它。:)(atom?list)应该只用于不正确的列表(不以nil结尾的列表),这种情况几乎不会发生。问题是:这不是尾部递归,因此除非保证参数列表很小,否则堆栈将被破坏。是的,这是显而易见的解决方案,但是我想要一个有效的方法:代码将被调用数千次。在你的问题中,你要求优雅。为了提高效率,您需要担心尾部递归,目前给出的解决方案还没有解决这一问题。如果您这样做(使用-lst压缩(cons0lst)),您将得到询问者想要的结果。
(define (f l res cur)
  (if (null? l)
    res
    (let ((next (car l)))
      (f (cdr l) (cons (- next cur) res) next))))

(define (do-work l)
  (reverse (f l '() 0)))

(do-work '(1 3 6 10 0))

==> (1 2 3 4 -10)
(define (solution ls)
  (let loop ((ls (cons 0 ls)))
    (let ((x (cadr ls)) (x_1 (car ls)))
      (if (null? (cddr ls)) (list (- x x_1))
          (cons (- x x_1) (loop (cdr ls)))))))

(display (equal? (solution '(1)) '(1))) (newline)
(display (equal? (solution '(1 5)) '(1 4))) (newline)
(display (equal? (solution '(1 3 6 10 0)) '(1 2 3 4 -10))) (newline)
(define (f l res cur)
  (if (null? l)
    res
    (let ((next (car l)))
      (f (cdr l) (cons (- next cur) res) next))))

(define (do-work l)
  (reverse (f l '() 0)))

(do-work '(1 3 6 10 0))

==> (1 2 3 4 -10)