我有一个列表 '(1 2 1 1 4 5)
并希望输出列表为 '((1 3)(2 1)(4 1)(5 1))
。我写了一段小代码,但我一直困惑于如何计算每个数字的基数,然后将其作为对放入列表中。有人可以看看我的代码并给出一些想法吗?
(define set2bags
(lambda (randlist)
(cond ((null? randlist) '())
(else
(sort randlist)
(makepairs randlist)))))
(define makepairs
(lambda (inlist)
(let ((x 0)) ((newlist '()))
(cond ((zero? (car inlist)) '())
(else
(eq? (car inlist)(car (cdr inlist)))
(+ x 1)
(makepairs (cdr inlist))
(append newlist (cons (car inlist) x)))))))
最佳答案
您当前的解决方案不正确 - 它甚至无法编译。让我们从头开始,使用 named let
用于遍历输入列表:
(define set2bags
(lambda (randlist)
(cond ((null? randlist) '())
(else (makepairs (sort randlist >))))))
(define makepairs
(lambda (inlist)
(let loop ((lst inlist)
(prv (car inlist))
(num 0)
(acc '()))
(cond ((null? lst)
(cons (list prv num) acc))
((= (car lst) prv)
(loop (cdr lst) prv (add1 num) acc))
(else
(loop (cdr lst) (car lst) 1 (cons (list prv num) acc)))))))
现在它按预期工作了:
(set2bags '(1 2 1 1 4 5))
=> '((1 3) (2 1) (4 1) (5 1))
诀窍是为基数保留一个计数器(我将其命名为 num
),并且只要前一个元素(我将其命名为 prv
)等于,就递增它当前元素。每当我们找到不同的元素时,我们都会向输出列表添加一个新的元素对(称为 acc
),并重置前一个元素和计数器。
关于list - 如何根据基数从数字列表中配对?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18117083/