Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 是否统计方案中列表中元素的出现次数? 这是非常容易的,如果我可以使用一个数组在命令语言或地图树结构在C++中。在计划中,我不知道如何开始这个想法?有人能帮我吗_Scheme - Fatal编程技术网

Scheme 是否统计方案中列表中元素的出现次数? 这是非常容易的,如果我可以使用一个数组在命令语言或地图树结构在C++中。在计划中,我不知道如何开始这个想法?有人能帮我吗

Scheme 是否统计方案中列表中元素的出现次数? 这是非常容易的,如果我可以使用一个数组在命令语言或地图树结构在C++中。在计划中,我不知道如何开始这个想法?有人能帮我吗,scheme,Scheme,谢谢,在球拍里,你可以做的 (count even? '(1 2 3 4)) 但更严重的是,使用Scheme中的列表执行此操作比您提到的要容易得多。列表要么是空的,要么是包含第一项和其余项的一对。在代码中遵循这个定义,你就会把它自己写出来 这里有一个开始的提示,基于此,这是一本学习这些东西的好书。从函数头开始-它应该接收谓词和列表: (define (count what list) ...) 添加输入的类型-什么是某个值,列表是一个内容列表: ;; count : Any List -

谢谢,

在球拍里,你可以做的

(count even? '(1 2 3 4))
但更严重的是,使用Scheme中的列表执行此操作比您提到的要容易得多。列表要么是空的,要么是包含第一项和其余项的一对。在代码中遵循这个定义,你就会把它自己写出来

这里有一个开始的提示,基于此,这是一本学习这些东西的好书。从函数头开始-它应该接收谓词和列表:

(define (count what list)
  ...)
添加输入的类型-什么是某个值,列表是一个内容列表:

;; count : Any List -> Int
(define (count what list)
  ...)
现在,给定列表的类型,以及列表的定义为空列表或两个对象对,我们需要检查它是哪种类型的列表:

;; count : Any List -> Int
(define (count what list)
  (cond [(null? list) ...]
        [else ...]))
第一种情况应该很明显:空列表中有多少项

对于第二种情况,您知道它是一个非空列表,因此您有两条信息:使用first或car获得的头部信息和使用rest或cdr获得的尾部信息:


您现在需要做的就是找出如何组合这两条信息来获得代码。最后一点让它变得非常简单的信息是:因为非空列表的尾部本身就是一个列表,所以您可以使用count来计算其中的内容。因此,您可以进一步得出结论,您应该在其中使用count what rest list。

在Scheme之类的函数式编程语言中,您必须以不同的方式思考,并利用列表的构造方式。不是通过增加索引来迭代列表,而是递归地遍历列表。你可以用carsingle元素删除列表的头部,你可以用cdr a列表本身获得尾部,你可以用cons将头部和尾部粘在一起。您的功能概述如下:

您必须将正在搜索的元素和当前计数传递给函数的每个调用 如果你点击了空列表,你就完成了列表,你可以输出结果 如果列表的car等于要查找的元素,则使用列表的cdr和计数器+1递归调用该函数 如果不是,则使用列表的cdr和与前面相同的计数器值递归调用该函数
在这个方案中,您通常将其用作穷人哈希表/字典上的一个索引。剩下的唯一问题是如何更新关联的元素。

您的问题不是很具体地说明要计算什么。我假设你想创建一些元素的频率表。有几种方法可以做到这一点。如果您使用的是Racket,请向下滚动至底部以获得我的首选解决方案

便携式、纯功能性,但冗长且缓慢 这种方法使用关联列表来保存元素及其计数。对于传入列表中的每个项目,它在列表中查找该项目,并将其存在的值递增,如果不存在,则将其初始化为1

(define (bagify lst)
  (define (exclude alist key)
    (fold (lambda (ass result)
            (if (equal? (car ass) key)
                result
                (cons ass result)))
          '() alist))
  (fold (lambda (key bag)
          (cond ((assoc key bag)
                 => (lambda (old)
                      (let ((new (cons key (+ (cdr old) 1))))
                        (cons new (exclude bag key)))))
                (else (let ((new (cons key 1)))
                        (cons new bag)))))
        '() lst))
递增是有趣的部分。为了纯粹的功能性,我们实际上不能更改列表的任何元素,而是必须排除正在更改的关联,然后将该关联与新值添加到结果中。例如,如果您有以下列表:

((foo . 1) (bar . 2) (baz . 2))
若要为baz的值添加1,则创建一个新的列表,将baz排除在外:

然后将baz的新价值添加回:

((baz . 3) (foo . 1) (bar . 2))
第二步是exclude函数所做的,可能是函数中最复杂的部分

便携、简洁、快速但不实用 更直接的方法是使用SRFI 69中的哈希表,然后为列表中的每个元素逐段更新它。因为我们直接更新哈希表,所以它不是纯函数式的

(define (bagify lst)
  (let ((ht (make-hash-table)))
    (define (process key)
      (hash-table-update/default! ht key (lambda (x) (+ x 1)) 0))
    (for-each process lst)
    (hash-table->alist ht)))
纯功能、简洁、快速,但不便于携带 这种方法使用特定于Racket的哈希表,与SRFI 69的哈希表不同,SRFI 69支持纯功能工作流。另一个好处是,这个版本也是三个版本中最简洁的

(define (bagify lst)
  (foldl (lambda (key ht)
           (hash-update ht key add1 0))
         #hash() lst))
您甚至可以使用以下方法来理解:

(define (bagify lst)
  (for/fold ((ht #hash()))
            ((key (in-list lst)))
    (hash-update ht key add1 0)))

这更多地表明了可移植SRFI 69散列库的缺点,而不是执行纯功能任务的方案的任何特定失败。有了正确的库,这项任务可以在功能上轻松实现。

@Eli Barzilay:老实说,我不是在寻找完整的代码。此外,我看不出你的回答中有任何暗示。我了解cdr、汽车等。我要寻找的是如何构造每个元素出现的列表。例如,我遇到了一个,将其增加1,但是我应该存储哪种结构,以及如何存储?添加了一个详细的解释-而不是书籍参考:你应该真正阅读那本书@伊莱·巴兹莱:非常感谢。你愿意吗
给我推荐一本书?我只是通过谷歌搜索来学习这门语言。不应该是笔记。如果你在自学这门语言,你应该读它。它是免费的,而且是在线的,所以没有任何借口可以避免它。我在寻找一个想法,一个暗示,而不是一个完整的解决方案。另外,除了计划背后的理论,我在你的回答中没有看到任何暗示。@Chan:我给了你一个暗示。通过移除头部,检查它,然后递归地继续使用尾部来浏览列表。谢谢,这会更好。然而,我需要花一些时间来思考。我会让你知道的。我把汽车和cdr弄混了。我修好了,错了。这与问题无关,而且现在,如果您需要在scheme中使用哈希表,那么您可以使用。。。哈希表。参见R6RS。我在后面的一条评论中指出,OP希望创建一个包含每个元素出现次数的列表。尽管如此,还是要感谢关于r6rs哈希表的提示。这不是问题。首先,非常感谢您的回答。然而,你的解决方案远远超出了我目前所知的范围,尤其是在没有任何评论的情况下。我真的不知道这是怎么回事。如果你有时间,你会把它分成一个较小的案例,并添加一些评论。当我避免弄清楚自己的时候,我可能听起来很懒,但在这一点上,这对我来说实在太过分了。我不认为我能从你的例子中学到什么。@Chan:如果你愿意坚持使用Racket,我用更简单的方法更新了我的答案。是的,这是一个基于折叠的解决方案!:-O
(define (bagify lst)
  (foldl (lambda (key ht)
           (hash-update ht key add1 0))
         #hash() lst))
(define (bagify lst)
  (for/fold ((ht #hash()))
            ((key (in-list lst)))
    (hash-update ht key add1 0)))