DrRacket – 查找字符列表中的元音总数
DrRacket – Finding total number of vowels in list of characters
我正在初学者语言模式下使用 DrRacket。
代码如下:
(define vowels '(#\a #\e #\i #\o #\u))
(define total 0)
(define (any-in-list lst check)
(cond
[(empty? lst) (+ 0 total)]
[(member? (first lst) check) (add1 total)]
[else (any-in-list (rest lst) check)]))
(define (count-vowels string)
(any-in-list (string->list string) vowels))
(count-vowels "how do i do this?")
total
值停留在 1
。调试后,我意识到第 2 个 cond
语句的计算结果为 #true,然后停止。更新 total
值后,如何在列表的其余部分继续使用?
您在找到匹配项时忘记递归。
此外,由于 total
为 0,因此 (+ 0 total)
始终为 0,而 (add1 total)
始终为 1。
不要尝试使用全局变量和变异 - 递归并使用递归值。
(cond
; The empty list contains nothing, so the result is 0.
[(empty? lst) 0]
; If the first element is a member, the result is
; one more than the count in the tail.
[(member? (first lst) check) (add1 (any-in-list (rest lst) check))]
; Otherwise, the count is the same as in the tail.
[else (any-in-list (rest lst) check)]))
molbdnilo 的回答解释了 OP 的问题并提供了正确的解决方案;
由于提到了“初学者语言”,因此可能值得
查看如何使用该方法构建解决方案
DrRacket 中的 BSL(初级学生语言)显然是针对它的。
按照 HtDF (How to Design Functions) 配方,可以编写以下内容
存根,包含签名和 用途和“check-expect”示例:
(注意:布局与 HtDF 约定略有不同)
(define (count-vowels str) ;; String -> Natural ) *stub define* ;; *signature*
;; produce the count of vowel characters in str ) *purpose statement*
0 ) ) *stub body* (a valid result)
(check-expect (count-vowels "") 0 ) ) *examples*
(check-expect (count-vowels "a") 1 ) )
(check-expect (count-vowels "b") 0 ) )
(check-expect (count-vowels "ab") 1 ) )
(check-expect (count-vowels "ae") 2 ) )
第一个check-expect已经通过;现在写 inventory 和 template;
count-vowels 必须对字符串中的每个字符做一些事情,但是没有
为此的标准 BSL 函数或模板。但是有一个做某事的模板
使用列表的元素:
(define (fn lox) ;; (Listof X) -> Y ) *template*
(cond )
[(empty? lox) ... ] #|base case|# ;; Y )
[else (... #|something|# ;; X Y -> Y )
(first lox) (fn (rest lox))) ])) )
(define vowels (list #\a #\e #\i #\o #\u)) ) *inventory*
(member? x lox) ;; X (Listof X) -> Bool )
(string->list str) ;; String -> (Listof Char) )
因此 count-vowels 可以是 string->list
的组合,并具有由此派生的函数
模板,其存根、签名和 check-expect 是:
(define (count-vowels-in-list loc) ;; (Listof Char) -> Natural
0)
(check-expect (count-vowels-in-list empty) 0 )
(check-expect (count-vowels-in-list (cons #\a '())) 1 ) ;; (+ 1 0)
(check-expect (count-vowels-in-list (cons #\b '())) 0 ) ;; (+ 0 0)
(check-expect (count-vowels-in-list (list #\a #\b)) 1 )
(check-expect (count-vowels-in-list (list #\a #\e)) 2 )
扩展模板并查看第一个 check-expect,|基本案例|可填写:
(define (count-vowels-in-list loc) ;; (Listof Char) -> Natural
(cond
[(empty? loc) 0 ]
[else (|something| (first loc) (count-vowels-in-list (rest loc))) ]))
对于接下来的两个 check-expects,(rest loc)
将是 '(),所以 (|something| #\a 0)
=> 1 但是
(|something| #\b 0)
=> 0
#\a 与 #\b 的区别在于 (member? #\a vowels)
=> #true 但是
(member? #\b vowels)
=> #false 所以 |something| 的描述性名称是 add-1-if-vowel:
(define (add-1-if-vowel chr n) ;; Char Natural -> Natural
(if (member? chr vowels)
(add1 n)
n))
所以按照这种系统化的设计方法开发出的完整解决方案是:
(define vowels (list #\a #\e #\i #\o #\u))
(define (add-1-if-vowel chr n) ;; Char Natural -> Natural
(if (member? chr vowels)
(add1 n)
n))
(define (count-vowels-in-list loc) ;; (Listof Char) -> Natural
(cond
[(empty? loc) 0 ]
[else (add-1-if-vowel (first loc) (count-vowels-in-list (rest loc))) ]))
(define (count-vowels str) ;; String -> Natural
(count-vowels-in-list (string->list str)))
(check-expect (count-vowels "") 0 )
(check-expect (count-vowels "a") 1 )
(check-expect (count-vowels "b") 0 )
(check-expect (count-vowels "ab") 1 )
(check-expect (count-vowels "ae") 2 )
(check-expect (count-vowels "how do i do this?") 5 ) ;; ^ (this is how :) ^
我正在初学者语言模式下使用 DrRacket。
代码如下:
(define vowels '(#\a #\e #\i #\o #\u))
(define total 0)
(define (any-in-list lst check)
(cond
[(empty? lst) (+ 0 total)]
[(member? (first lst) check) (add1 total)]
[else (any-in-list (rest lst) check)]))
(define (count-vowels string)
(any-in-list (string->list string) vowels))
(count-vowels "how do i do this?")
total
值停留在 1
。调试后,我意识到第 2 个 cond
语句的计算结果为 #true,然后停止。更新 total
值后,如何在列表的其余部分继续使用?
您在找到匹配项时忘记递归。
此外,由于 total
为 0,因此 (+ 0 total)
始终为 0,而 (add1 total)
始终为 1。
不要尝试使用全局变量和变异 - 递归并使用递归值。
(cond
; The empty list contains nothing, so the result is 0.
[(empty? lst) 0]
; If the first element is a member, the result is
; one more than the count in the tail.
[(member? (first lst) check) (add1 (any-in-list (rest lst) check))]
; Otherwise, the count is the same as in the tail.
[else (any-in-list (rest lst) check)]))
molbdnilo 的回答解释了 OP 的问题并提供了正确的解决方案; 由于提到了“初学者语言”,因此可能值得 查看如何使用该方法构建解决方案 DrRacket 中的 BSL(初级学生语言)显然是针对它的。
按照 HtDF (How to Design Functions) 配方,可以编写以下内容
存根,包含签名和 用途和“check-expect”示例:
(注意:布局与 HtDF 约定略有不同)
(define (count-vowels str) ;; String -> Natural ) *stub define* ;; *signature*
;; produce the count of vowel characters in str ) *purpose statement*
0 ) ) *stub body* (a valid result)
(check-expect (count-vowels "") 0 ) ) *examples*
(check-expect (count-vowels "a") 1 ) )
(check-expect (count-vowels "b") 0 ) )
(check-expect (count-vowels "ab") 1 ) )
(check-expect (count-vowels "ae") 2 ) )
第一个check-expect已经通过;现在写 inventory 和 template; count-vowels 必须对字符串中的每个字符做一些事情,但是没有 为此的标准 BSL 函数或模板。但是有一个做某事的模板 使用列表的元素:
(define (fn lox) ;; (Listof X) -> Y ) *template*
(cond )
[(empty? lox) ... ] #|base case|# ;; Y )
[else (... #|something|# ;; X Y -> Y )
(first lox) (fn (rest lox))) ])) )
(define vowels (list #\a #\e #\i #\o #\u)) ) *inventory*
(member? x lox) ;; X (Listof X) -> Bool )
(string->list str) ;; String -> (Listof Char) )
因此 count-vowels 可以是 string->list
的组合,并具有由此派生的函数
模板,其存根、签名和 check-expect 是:
(define (count-vowels-in-list loc) ;; (Listof Char) -> Natural
0)
(check-expect (count-vowels-in-list empty) 0 )
(check-expect (count-vowels-in-list (cons #\a '())) 1 ) ;; (+ 1 0)
(check-expect (count-vowels-in-list (cons #\b '())) 0 ) ;; (+ 0 0)
(check-expect (count-vowels-in-list (list #\a #\b)) 1 )
(check-expect (count-vowels-in-list (list #\a #\e)) 2 )
扩展模板并查看第一个 check-expect,|基本案例|可填写:
(define (count-vowels-in-list loc) ;; (Listof Char) -> Natural
(cond
[(empty? loc) 0 ]
[else (|something| (first loc) (count-vowels-in-list (rest loc))) ]))
对于接下来的两个 check-expects,(rest loc)
将是 '(),所以 (|something| #\a 0)
=> 1 但是
(|something| #\b 0)
=> 0
#\a 与 #\b 的区别在于 (member? #\a vowels)
=> #true 但是
(member? #\b vowels)
=> #false 所以 |something| 的描述性名称是 add-1-if-vowel:
(define (add-1-if-vowel chr n) ;; Char Natural -> Natural
(if (member? chr vowels)
(add1 n)
n))
所以按照这种系统化的设计方法开发出的完整解决方案是:
(define vowels (list #\a #\e #\i #\o #\u))
(define (add-1-if-vowel chr n) ;; Char Natural -> Natural
(if (member? chr vowels)
(add1 n)
n))
(define (count-vowels-in-list loc) ;; (Listof Char) -> Natural
(cond
[(empty? loc) 0 ]
[else (add-1-if-vowel (first loc) (count-vowels-in-list (rest loc))) ]))
(define (count-vowels str) ;; String -> Natural
(count-vowels-in-list (string->list str)))
(check-expect (count-vowels "") 0 )
(check-expect (count-vowels "a") 1 )
(check-expect (count-vowels "b") 0 )
(check-expect (count-vowels "ab") 1 )
(check-expect (count-vowels "ae") 2 )
(check-expect (count-vowels "how do i do this?") 5 ) ;; ^ (this is how :) ^