List 如何在Scheme中查找列表中的重复字符数
我试图在Scheme中创建一个函数,返回一个字符在列表中重复的次数。 例如,如果我有(列表2 6'a'b'a'a 2) 结果必须是((2.2)(6.1)(a.3)(b.1)) 它不需要以最有效的方式编写,只需要简单易懂即可List 如何在Scheme中查找列表中的重复字符数,list,scheme,List,Scheme,我试图在Scheme中创建一个函数,返回一个字符在列表中重复的次数。 例如,如果我有(列表2 6'a'b'a'a 2) 结果必须是((2.2)(6.1)(a.3)(b.1)) 它不需要以最有效的方式编写,只需要简单易懂即可 提前感谢您的帮助:)因为这似乎是家庭作业,您没有发布任何代码,我们对您的限制和您当前对方案的了解一无所知,所以很难回答 基本上,您可以使用散列映射有效地执行此操作,或者使用两个嵌套循环执行此操作的效率较低。我将解释后一种情况,让您开始 我假设你知道如何循环浏览列表 所以基本上
提前感谢您的帮助:)因为这似乎是家庭作业,您没有发布任何代码,我们对您的限制和您当前对方案的了解一无所知,所以很难回答 基本上,您可以使用散列映射有效地执行此操作,或者使用两个嵌套循环执行此操作的效率较低。我将解释后一种情况,让您开始 我假设你知道如何循环浏览列表 所以基本上你需要
- 1) 循环浏览你的列表
- 2) 对于列表中的每个元素(我们称之为e)
- 3) 再次在列表上循环,计算您找到的(e)中有多少个
- 4) 集合(e)和计数循环的结果
- 2) 对于列表中的每个元素(我们称之为e)
'((2 . 2) (6 . 1) (a . 3) (b . 1) (a . 3) (a . 3) (2 . 2))
很接近。。。但不正确,因为您数了几次某些元素
因此,除了上述内容之外,您还需要一种跟踪您已经遇到的每个元素的方法,并且只有在遇到新元素时才需要执行步骤3)和步骤4)。根据您的代码,可以通过另一个列表进行跟踪,或者只需检查当前的结果列表
如果您有任何代码要显示,请更新您的问题,我们可以提供更多帮助
编辑
好的,既然GoZoner已经发布了代码,我有两个备选版本供您选择。我希望你研究所有这些,并做出自己的决定,而不是简单地复制一个
首先,我描述的版本;与GoZoner的版本相反,它不使用可变列表,但比可变版本慢:
(define (how-many lst)
(let loop ((lst2 lst) (res '()))
(if (empty? lst2)
(reverse res)
(let ((c (car lst2)))
(loop (cdr lst2)
(if (assoc c res)
res
(cons (cons c (count (lambda (e) (eq? e c)) lst)) res)))))))
=> '((2 . 2) (6 . 1) (a . 3) (b . 1))
如果您想使用可变结构(我也会),我建议使用可变哈希表。以下示例为Racket中的示例,但如果需要,则很难适应R6RS方案:
(define (how-many lst)
(let ((res (make-hash)))
(for-each (lambda (e) (hash-update! res e add1 0)) lst)
(hash->list res)))
=> '((6 . 1) (a . 3) (b . 1) (2 . 2))
请注意,哈希表不考虑顺序,因此您将得到相同的结果,但对的顺序可能不同(甚至在一次调用到下一次调用时有所不同)。类似于以下内容:
(define (character-count list)
(assert (list? list))
(let looking ((list list) (rslt '()))
(cond ((null? list) rslt)
((assoc (car list) rslt) =>
(lambda (pair)
(set-cdr! pair (+ 1 (cdr pair)))
(looking (cdr list) rslt)))
(else (looking (cdr list)
(cons (cons (car list) 1) rslt))))))
> (character-count '(2 a 2 a b c 2))
((c . 1) (b . 1) (a . 2) (2 . 3))
我得了“A” 到目前为止你试过什么?请发布您为解决此问题而编写的代码,指出您遇到麻烦的确切部分。您能告诉我assert正在做什么吗?