如何在Racket中复用内置算法实现类似C++ std::adjacent_difference的功能?
嘿,这个问题我太懂了!之前我也纠结过怎么用Racket的内置函数优雅实现类似C++ std::adjacent_difference的功能,不想自己写一堆递归或者新函数。其实核心思路很简单——利用map配合列表的切片操作就能搞定!
情况1:只需要相邻元素的差值列表(长度比原列表少1)
如果你只需要后一个元素减前一个元素的结果列表,直接把原列表和它的cdr版本传给map就行。比如:
(define lst '(1 3 6 10)) (map - (cdr lst) lst) ; 输出 '(2 3 4)
原理很直白:(cdr lst)会去掉原列表的第一个元素,这样两个列表的长度就匹配了,map会逐个把对应位置的元素传入减法函数,得到相邻元素的差值。
情况2:和C++ std::adjacent_difference完全一致(保留第一个元素)
如果需要和C++的行为完全对齐——结果列表的第一个元素是原列表的第一个元素,后续元素是相邻差值,只需要把原第一个元素和上面的差值列表拼接起来就行:
(define lst '(1 3 6 10)) (cons (car lst) (map - (cdr lst) lst)) ; 输出 '(1 2 3 4)
这个写法完全复用了Racket的cons、car、cdr和map这些内置函数,没有任何自定义函数,非常简洁优雅。
扩展:自定义差值操作
如果你的“差值”不是简单的减法,而是其他二元逻辑,只需要把-换成对应的函数就行。比如想计算相邻元素的乘积差:
(define lst '(2 4 6 8)) (map (lambda (a b) (* a (- a b))) (cdr lst) lst) ; 输出 '(8 12 16)
这样就完全满足你“复用Racket内置算法”的需求啦,不需要写任何新函数,全靠原生函数组合实现。
内容的提问来源于stack exchange,提问作者Stefan Dorn
相关产品推荐
相关产品推荐

