如何在Racket中实现支持自定义相似性判定的列表去重函数
Racket 支持自定义相似性判定的列表去重函数实现
核心实现思路
- 采用尾递归遍历原列表,同时维护已保留元素的集合作为中间状态
- 对每个当前遍历的元素,通过传入的相似性函数判断是否已在已保留集合中出现过
- 未出现过则加入保留集合,否则跳过,最终反转中间集合得到保持原顺序的去重结果
- 默认使用
eq?作为相似性判定函数,支持用户传入自定义对称判定函数
完整代码实现
(define (remove-duplicates* lst [same? eq?]) (let loop ([remaining lst] ; 剩余待遍历的元素 [seen '()]) ; 已确认保留的元素集合 (cond [(empty? remaining) (reverse seen)] [else (define current (car remaining)) ; 检查当前元素是否已经出现在保留集合中 (if (ormap (lambda (x) (same? x current)) seen) (loop (cdr remaining) seen) (loop (cdr remaining) (cons current seen)))])))
使用示例
- 默认
eq?判定去重
(remove-duplicates* '(1 2 2 3 'a 'a 4)) ; 输出:'(1 2 3 'a 4)
- 自定义大小写不敏感的字符串去重
(remove-duplicates* '("apple" "Apple" "banana" "APPLE") string-ci=?) ; 输出:'("apple" "banana")
- 按绝对值相等对数值列表去重
(remove-duplicates* '(1 -1 2 3 -2) (lambda (a b) (= (abs a) (abs b)))) ; 输出:'(1 2 3)
内容的提问来源于stack exchange,提问作者Danilobol
相关产品推荐
相关产品推荐

