统计一个字母在列表中出现的次数
Count the occurrence of a letter in a list
到目前为止我已经试过了,但我得到了 1:
(define occur
(lambda (a s)
(count (curry string-contains? a) s)))
例如:(occur "u" '("u" "uaub" "ubub"))
=> 1
应该是5
想避免使用咖喱,因为我还不知道它是如何工作的:
Dr. Racket Recursion count occurrences
什么是 (string-contains? "abc" "b")
?
什么是 (string-contains? "b" "abc")
?
string-contains?
的语法是:
(string-contains? haystack needle)
这意味着 你在调用
时使用了错误的参数
(curry string-contains? a)
这里用haystack
标识a
:要搜索的字符串,不是要搜索的字符串。 curry
returns 一个单参数函数,它接受一个 needle
参数,并搜索它是否出现在 a
中。而你想要的是相反的方式。
幸运的是,Racket 为您提供了解决方案:只需将字母 r
添加到 curry
符号:改用 curryr
函数,它绑定最右边的参数,并保留左边的参数免费:
(curryr string-contains? a)
这将使 a
与 needle
参数(在较大的 haystack
中找到的东西)一致,返回一个接受 haystack
参数的函数。
这个函数就是你应用到列表中每个元素的函数,并计算它returns true 的次数。
curry
与 curryr
对比 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))
.
部分应用和柯里化可以可视化为一种糖,可以理解为对显式和更冗长 lambda
语法的转换。如果您对某些柯里化情况感到困惑,这有时会有所帮助。
这会删除字符串连接的 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 ""))))
也可以使用以下循环来计算出现次数。它使用 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
到目前为止我已经试过了,但我得到了 1:
(define occur
(lambda (a s)
(count (curry string-contains? a) s)))
例如:(occur "u" '("u" "uaub" "ubub"))
=> 1
应该是5
想避免使用咖喱,因为我还不知道它是如何工作的: Dr. Racket Recursion count occurrences
什么是 (string-contains? "abc" "b")
?
什么是 (string-contains? "b" "abc")
?
string-contains?
的语法是:
(string-contains? haystack needle)
这意味着 你在调用
时使用了错误的参数(curry string-contains? a)
这里用haystack
标识a
:要搜索的字符串,不是要搜索的字符串。 curry
returns 一个单参数函数,它接受一个 needle
参数,并搜索它是否出现在 a
中。而你想要的是相反的方式。
幸运的是,Racket 为您提供了解决方案:只需将字母 r
添加到 curry
符号:改用 curryr
函数,它绑定最右边的参数,并保留左边的参数免费:
(curryr string-contains? a)
这将使 a
与 needle
参数(在较大的 haystack
中找到的东西)一致,返回一个接受 haystack
参数的函数。
这个函数就是你应用到列表中每个元素的函数,并计算它returns true 的次数。
curry
与 curryr
对比 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))
.
部分应用和柯里化可以可视化为一种糖,可以理解为对显式和更冗长 lambda
语法的转换。如果您对某些柯里化情况感到困惑,这有时会有所帮助。
这会删除字符串连接的 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 ""))))
也可以使用以下循环来计算出现次数。它使用 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