【问题标题】:Scheme - function to count occurrences of atom in argumentScheme - 计算参数中原子出现次数的函数
【发布时间】:2021-04-06 21:57:58
【问题描述】:

我是方案新手,正在尝试学习函数。我想创建一个函数,我可以在其中计算参数中原子“a”的所有出现次数。这是我到目前为止所写的。我不确定在第三种情况下该写什么。请帮忙。

(define (count-a arg)
   (COND
     ((null? arg) 0)
     ((eq? arg 'a) 1)
     ((list? arg) ( ___ + ( ___ count-a arg)))
     (else 0)
     
))

这是我想要的输出:

(count-a 'a) 1

(count-a 'aa) 0

(count-a '(a)) 1

(count-a '(ab c) 0

(count-a '(a (b c) (c (d a) a) (((a b))))) 5

【问题讨论】:

  • 你对第三个条件中的模式有合适的形式有多大信心?
  • 一个列表有两个部分,一个头和一个尾。看起来您想计算头部的所有 a,尾部的所有 a,然后将它们相加。但是,您的骨架表达式格式不正确,因为在 Scheme 中您会编写 (+ ....) 并且递归函数调用是 (count-a something),在 count-a 之前没有一个术语
  • @coredump 或者是( _red..._ + ( _ma.._ count-a arg))。 Scheme中没有尖锐的引用。 :)
  • 这是作业吗?您希望我们给您答案或提示吗?你了解过高阶函数吗,比如filterfold? ------ 还有,(count-a '(a (b c) (c (d a) a) (((a b))))) 应该是 4,不是吗?
  • @Will Ness 恐怕你是对的 :'(

标签: function functional-programming scheme lisp


【解决方案1】:

(___ + ( ___ count-a arg)) 对我来说似乎不合适。请记住,Scheme 是一种前缀语言。是 (+ 1 2 3) 而不是 1 + 2 + 3

在第三个中,您有两个列表部分。例如。 '(a a) 所以你需要在列表的carcdr 上调用count-a 并将结果加在一起。例如。 (count-a '(a a)) 应该与(+ (count-a 'a) (count-a '(a)) 给出相同的结果

祝你好运

【讨论】:

  • 没错,只是不适合新手。 :) + 是“功能”的函数参数(在旧的 FP 中)。
  • @WillNess 在这个答案中演示 map 会让人困惑:-o
  • reduce 更容易混淆。 :)
【解决方案2】:

欢迎来到 Stack Overflow!

解决方案:

(define (count-a  arg)
  (cond ((null? arg) 0)
        ((not (pair? arg)) 
          (if (equal? arg 'a)
              1
              0))
        ;; At this point we know arg is a pair, and we recurse.
        (else (+ (count-a (car arg)) (count-a (cdr arg))))))

测试:

这是您指定的测试,压缩成一行。

;; Chibi-Scheme REPL - other implementations might look different.
> (map  count-a '(a aa (a) (ab c) (a (b c) (c (d a) a) (((a b))))))
(1 0 1 0 4)

如果arg 是一个点对,你没有说你想要发生什么。但让我们看看它只是为了好玩。

> (map count-a '((ab . '()) (ab . a) (a . a)))
(0 1 2)

因此,当我对我的代码运行您的最后一个测试时,它会在您期望的 5 处产生 4。我认为我的代码是正确的,而您的测试规范是不正确的,因为 'a 的参数中只有四个实例count-a.

讨论:

您在标题中指定count-a 函数将计算的对象是原子。所以你必须检查arg 是否是一个原子。由于Scheme 没有atom? 函数,我假设原子是不是'() 并且不是一对的任何东西。 (这与 Common Lisp 的 atom 函数以及其他 Lisp 方言一致。)

由于您的代码已经处理了arg'(),我们只需要处理arg 是否是一对。

如果arg 不是 一对并且(equal? arg 'a),则(count-a arg) 等于1。否则,它等于0。

如果arg 一对,我们可以递归到car arg)(cdr arg),不管arg的嵌套有多深,只要我们找到一个等于的原子就增加我们的计数a.

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2011-08-10
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多