List 如何使用Racket语言为嵌套列表创建计数器?
我试图在Dr Racket中创建一个计数器,它将遍历嵌套列表并输出计数 (我在列表中留下了所有的3) 它目前正在输出3(这是前三个3) 我假设它将到达第一个嵌套列表的末尾,并在该点停止,但我似乎不知道该怎么做。(是的,这是一项任务,但这是我们在球拍方面的第二项任务,也是春假期间的第二项任务。我们回去的那天就要交了。) 我不希望你给我答案,只是解释一下应该改变什么,或者教我比我的教授更多的语言知识 因此,我将列表更改为(genCounter'(3(3(3(3))3(3)))30,它返回了6(我测试发现它是第一个返回的6)。我相信,当它到达其中一个列表的末尾时,它会停止执行函数,但正如我所说的,我不知道要修复它到底要实现什么(尽管我知道它有什么问题) 以下是我最终创造的:List 如何使用Racket语言为嵌套列表创建计数器?,list,nested,racket,counter,nested-lists,List,Nested,Racket,Counter,Nested Lists,我试图在Dr Racket中创建一个计数器,它将遍历嵌套列表并输出计数 (我在列表中留下了所有的3) 它目前正在输出3(这是前三个3) 我假设它将到达第一个嵌套列表的末尾,并在该点停止,但我似乎不知道该怎么做。(是的,这是一项任务,但这是我们在球拍方面的第二项任务,也是春假期间的第二项任务。我们回去的那天就要交了。) 我不希望你给我答案,只是解释一下应该改变什么,或者教我比我的教授更多的语言知识 因此,我将列表更改为(genCounter'(3(3(3(3))3(3)))30,它返回了6(我测试
(define (genCounter lst target)
(if (null? lst) 0
(let ((current (first lst)))
(cond
((list? current)
(+ (genCounter current target) (genCounter (rest lst) target)))
((eq? current target)
(+ 1 (genCounter (rest lst) target)))
(else
(genCounter (rest lst) target))))))
首先,我们不要将标识符命名为
list
list
是一个构造列表的函数。如果使用此名称,则会隐藏它,因此无法在函数中使用它!下面,我将使用lst
现在,对于你的问题,答案是,你的第二个分支是错误的:
[(list? (first lst)) (genCounter (first lst) val c)]
这样做的目的是:“如果第一个元素是一个列表,那么深入到这个子列表中,数一数,然后回答”
你能明白为什么错了吗
假设要在以下列表中计算2:
(list (list 2 2 2) 2 (list 2 (list 2)))
因为第一个元素(列表2)
,是一个列表,所以它进入这个子列表并计数2。答案是3。但是,预期的输出是6
问题是,您不希望只在第一个元素中计算2,而是希望在第一个元素中计算2
(list ... >>> 2 (list 2 (list 2)) <<<)
(list…>>>>2(list 2(list 2))首先,我们不要将标识符命名为list
list
是一个构造列表的函数。如果使用此名称,则会隐藏它,因此无法在函数中使用它!下面,我将使用lst
现在,对于你的问题,答案是,你的第二个分支是错误的:
[(list? (first lst)) (genCounter (first lst) val c)]
这样做的目的是:“如果第一个元素是一个列表,那么深入到这个子列表中,数一数,然后回答”
你能明白为什么错了吗
假设要在以下列表中计算2:
(list (list 2 2 2) 2 (list 2 (list 2)))
因为第一个元素(列表2)
,是一个列表,所以它进入这个子列表并计数2。答案是3。但是,预期的输出是6
问题是,您不希望只在第一个元素中计算2,而是希望在第一个元素中计算2
(list ... >>> 2 (list 2 (list 2)) <<<)
(列表…>>>2(列表2)(列表2))既然您现在有了一个有效的解决方案,我将向您展示
工作代码的替代方案
(定义(genCounter lst目标)
(如果(空?lst)
0
(+(genCounter(rest lst)目标)
(让((x(第一个lst)))
(如果(列表?x)
(genCounter x目标)
(如果(eqv?x目标)10()()())))
注意
- 当第一个元素不匹配时,以添加
0
为代价,代码中的冗余更少
- 您不应使用
eq?
表示数字,而应使用=
或eqv?
;同时查看equal?
与累加器一起工作的代码(如在第一个版本中)
(定义(genCounter lst目标)
(let循环((lst lst)(计数0))
(如果(空?lst)
计数
(循环(静止lst)
(让((x(第一个lst)))
(如果(列表?x)
(循环x计数)
(如果(eqv?x目标)(添加1计数)计数‘‘‘‘‘‘‘‘‘‘)
感兴趣的:
- 我将累加器
count
移动到一个内部过程(在本例中为命名let),它不应该是主过程签名的一部分
- 所有的神奇之处都发生在最后对
循环
的递归调用中,如果第一个元素是列表,则还包括一个额外的递归调用
既然您现在有了一个有效的解决方案,我将向您展示
工作代码的替代方案
(定义(genCounter lst目标)
(如果(空?lst)
0
(+(genCounter(rest lst)目标)
(让((x(第一个lst)))
(如果(列表?x)
(genCounter x目标)
(如果(eqv?x目标)10()()())))
注意
- 当第一个元素不匹配时,以添加
0
为代价,代码中的冗余更少
- 您不应使用
eq?
表示数字,而应使用=
或eqv?
;同时查看equal?
与累加器一起工作的代码(如在第一个版本中)
(定义(genCounter lst目标)
(let循环((lst lst)(计数0))
(如果(空?lst)
计数
(循环(静止lst)
(让((x(第一个lst)))
(如果(列表?x)
(循环x计数)
(如果(eqv?x目标)(添加1计数)计数‘‘‘‘‘‘‘‘‘‘)
感兴趣的:
- 我将累加器
count
移动到一个内部过程(在本例中为命名let),它不应该是主过程签名的一部分
- 所有的神奇之处都发生在最后对
循环
的递归调用中,如果第一个元素是列表,则还包括一个额外的递归调用
发布您的代码,而不是代码的图像。我已将其更新为包含实际代码。发布您的代码,而不是代码的图像。我已将其更新为包含实际代码。我知道您在说什么(它在第一个子列表后结束),但我不知道如何修复它。我需要在某个时候浏览列表的其余部分,但我