You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dr.Racket中item-counts列表元素计数函数实现问题

Racket item-counts 函数实现方案

现有代码存在3个直接导致运行错误、结果结构异常的问题:

  • 基础分支返回值类型不统一:处理单元素列表时直接返回裸元素(字符串、布尔值等),其余递归分支返回列表,后续拼接时必然出现层级混乱
  • 缺失核心计数逻辑:仅完成了元素相等判断,未实现「匹配到重复元素时计数+1、未匹配时新增计数条目」的逻辑
  • cons 语法使用错误:Racket 中 cons 仅接收2个参数,测试用例中传入3~4个参数的写法本身不符合语法,计数结果的标准结构为关联列表:每个元素是 (值 . 计数) 格式的 cons 对,所有 cons 对组成最终结果列表。

可直接运行的正确代码

首先修正测试用例为合法语法:

(check-expect
 (item-counts
  (cons "hello"
        (cons "hey"
              (cons "hello" '())))
  equal?)
 (list (cons "hello" 2)
       (cons "hey" 1)))

(check-expect
 (item-counts
  (cons #true
        (cons #false
              (cons #true '())))
  equal?)
 (list (cons #true 2)
       (cons #false 1)))

函数实现采用原生递归,每次处理当前元素前先递归得到剩余列表的统计结果,再判断当前元素是否已被统计:匹配到则更新计数替换旧条目,未匹配则新增计数为1的新条目。

(define (item-counts lop ef)
  (cond
    ; 空输入对应空统计结果
    [(empty? lop) '()]
    [else
     (define rest-counts (item-counts (rest lop) ef))
     (define current (first lop))
     ; 在已有统计结果中查找当前元素
     (define exist-pair (assf (lambda (x) (ef current x)) rest-counts))
     (if exist-pair
         ; 存在重复:移除旧条目,追加计数+1的新条目
         (cons (cons current (add1 (cdr exist-pair)))
               (filter (lambda (p) (not (ef current (car p)))) rest-counts))
         ; 不存在重复:新增计数为1的条目
         (cons (cons current 1) rest-counts))]))

之前调用append出现嵌套列表的原因

append 要求所有传入参数必须是列表类型,之前的代码因为基础分支返回非列表类型的裸元素,传入append时会被当成单个列表元素处理,而非作为列表拼接,最终生成多层嵌套的错误结构。

如果需要返回键值交替的扁平列表(如(list "hello" 2 "hey" 1)),只需要在上述函数的最终返回结果外调用flatten拉平结构即可。但关联列表是Racket生态中处理键值计数场景的标准结构,后续做查询、更新、遍历操作都更便捷。


内容的提问来源于stack exchange,提问作者daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 21:24:56