计算列表中字母的出现次数

时间:2016-09-23 03:57:07

标签: lambda scheme lisp racket

到目前为止,我已经尝试了这个,但我得到了1:

(define occur
  (lambda (a s)
    (count (curry string-contains? a) s)))

例如:(occur "u" '("u" "uaub" "ubub")) => 1

应该是5

我想避免使用咖喱,因为我不知道它是如何工作的: Dr. Racket Recursion count occurrences

4 个答案:

答案 0 :(得分:1)

什么是(string-contains? "abc" "b")

什么是(string-contains? "b" "abc")

答案 1 :(得分:1)

string-contains?的语法是:

(string-contains? haystack needle)

这意味着**当你调用

时,你正在讨论错误的参数*
(curry string-contains? a)

这标识a haystack:要搜索的字符串,而不是要搜索的字符串。 curry返回一个单参数函数,该函数接受needle参数,并搜索它是否出现在a中。而你想要的却是另一种方式。

幸运的是,Racket为您提供了解决方案:只需将字母r添加到curry符号:改为使用curryr函数,它绑定最右边的参数,并保留左边的空格:

(curryr string-contains? a)

这将使aneedle参数(在较大的haystack中找到的东西)一致,返回一个带有haystack参数的函数。

然后,此函数应用于列表的每个元素,并计算它返回true的次数。

currycurryr相对于cons函数的插图:

(map (curry cons 'a) '(1 2 3)) -> ((a . 1) (a . 2) (a . 3))
(map (curryr cons 'd) '(1 2 3)) -> ((1 . d) (2 . d) (3 . d))

(curry cons 'a)有效地为我们提供了函数(lambda (arg) (cons 'a arg))

(curryr cons 'd)有效地为我们提供了函数(lambda (arg) (cons arg 'd))

部分应用和currying可以看作是糖,可以理解为对明确且更冗长的lambda语法的转换。如果你对一些讨厌的情况感到困惑,那么这可能会有所帮助。

答案 2 :(得分:0)

这会删除字符串连接的reduce。

(define (how-many items char)
  (define r (regexp (format "[^~a]" char)))
  (string-length (regexp-replace* r (string-join items) "")))

; call it with (how-many '("u" "uaub" "ubub") #\u)

但如果你不想一次把所有字符串塞在一起,你可以将各个结果加起来。

(define (how-many items char)
  (define r (regexp (format "[^~a]" char)))
  (for/sum ((text (in-list items)))
    (string-length (regexp-replace* r text ""))))

答案 3 :(得分:0)

以下循环也可用于计算出现次数。它使用count函数查找从字符串中获取的列表:

(define (occur c l)
  (let loop ((l l)
             (n 0))
    (cond
      [(empty? l) n]
      [else (loop (rest l)
                  (+ n
                     (count (lambda(x) (equal? x c))
                            (string->list (first l)))))])))

请注意" u"将作为角色发送。

测试:

(occur #\u '("u" "uaub" "ubub"))

输出:

5