映入眼帘,
摘要
无法将'(+)或'( - )作为数据传递给cond(未评估)。它们自己返回(+)或( - ),作为参数返回标识元素(0)。
HELP!
对于代码中的非标准方案。
在这本书中; 句子是平面列表和 单词是sybmols和字符串。 在simple.scm中有三个高阶函数/过程,library的一部分用于说明主题,每一个,保持和累积;
练习8.11是一个gpa计算器程序。通过指令,不允许lambda或递归(如果按顺序读取,则尚未教授)。
我尝试的第一个实现在一个句子中取得多个等级并输出单个句子,每个句子都有一个等级。然后它将此输出传递给辅助程序。
如果单级输出有+或 - 它被分开,例如'(a +)变成'(a)和'(+),然后所有输出都传递给另一个辅助程序。
然后cond分配分数
a 4
b 3
c 2
d 1
e 0
+ 0.33
- -0.33
这只能在我的头脑中起作用(为什么计算机不像脑子一样工作?)当像'(a +)或'(a-)这样的分数被分开时,'(a)被正确处理但是'( +)或'( - )求值为identity元素(0)并且无法添加到gpa。
有没有办法让'(+)和'( - )作为数据而不是作为表达式传递?或者,我可以在返回(0)之前将它们转换为cond中可用的任意数据吗?
目前的版本,每个年级的冗长cond,工作,但是很可怕。使实现感觉像命令式而不是函数式编程。
返回错误的gpa(不添加0.33或-0.33): 此外,输入类型检入(gpa-helper)失败了。
(define (gpa gradesset)
(/ (accumulate + (every gpa-helper gradesset)) (count gradesset)) )
(define (gpa-helper gradewrd)
(cond ((or (< (count gradewrd) 1) (> (count gradewrd) 2)) '(Please use valid grade input))
((= (count gradewrd) 1) (gpa-allocator (keep valid-grade? gradewrd)))
((= (count gradewrd) 2) (every gpa-helper (keep valid-grade? gradewrd)))
(else '(Please check that all grades entered are valid)) ) )
(define (gpa-allocator gradeletter+-)
(cond ((equal? gradeletter+- 'a) 4)
((equal? gradeletter+- 'b) 3)
((equal? gradeletter+- 'c) 2)
((equal? gradeletter+- 'd) 1)
((equal? gradeletter+- 'e) 0)
((equal? gradeletter+- +) .33)
((equal? gradeletter+- -) (- .33))
(else 0) ) )
(define (valid-grade? gradein)
(if (member? gradein '(+ - a+ a a- b+ b b- c+ c c- d+ d d- e)) #t #f) )
重做版本,返回单个分数的句子。由'(+)和'( - )返回的0在这里可见。实现成功的输入类型检查,但引入了新的问题。 (累积结果为一个)
(define (gpa gradesset)
(every gpa-cleaner gradesset) )
(define (gpa-cleaner gradewrd)
(cond ((or (< (count gradewrd) 1) (> (count gradewrd) 2)) 0)
(else (every gpa-accumulator gradewrd)) ) )
(define (gpa-accumulator gradewrd)
(/ (accumulate + (every gpa-helper gradewrd)) (count gradewrd)) )
(define (gpa-helper gradewrd)
(cond ((= (count gradewrd) 1) (gpa-allocator (keep valid-grade? gradewrd)))
((= (count gradewrd) 2) (every gpa-helper (keep valid-grade? gradewrd)))
(else '(Please check that all grades entered are valid)) ) )
(define (gpa-allocator gradeletter+-)
(cond ((equal? gradeletter+- 'a) 4)
((equal? gradeletter+- 'b) 3)
((equal? gradeletter+- 'c) 2)
((equal? gradeletter+- 'd) 1)
((equal? gradeletter+- 'e) 0)
((equal? gradeletter+- +) .33)
((equal? gradeletter+- -) (- .33))
(else 0) ) )
(define (valid-grade? gradein)
(if (member? gradein '(+ - a b c d e)) #t #f) )
使用带有Slib 3b3的SCM版本5e7,随Simply Scheme提供的附加库(在上面的背景下提供链接 - simply.scm,functions.scm,ttt.scm,match.scm,database.scm)和我在哪里的库为每次加载的练习输入我的答案。
答案 0 :(得分:2)
如果您需要将+
或-
作为符号(而非作为程序)传递,则必须先引用它:
'+
'-
例如:
((equal? gradeletter+- '+) .33)
((equal? gradeletter+- '-) -.33)
但从上下文来看,我不认为gpa-allocator
程序是正确的。成绩可以是a
或a+
,条件意味着+
或-
是实际成绩,这是错误的。
也许您应该将成绩表示为字符串并检查(使用string-ref)
字符串中的第一个字符以确定它是#\a, #\b, #\c, #\d, #\e
和(如果字符串的长度大于1)测试第二个字符字符串中的#\+
或#\-
。然后您可以通过添加两个值来确定等级的适当值。或者,您可以将成绩作为符号传递并将其转换为字符串。是我的意思:
(define (gpa-allocator gradeletter+-)
(let ((grade (symbol->string gradeletter+-)))
(+ (case (string-ref grade 0)
((#\a #\A) 4)
((#\b #\B) 3)
((#\c #\C) 2)
((#\d #\D) 1)
((#\e #\E) 0)
(else 0))
(if (> (string-length grade) 1)
(case (string-ref grade 1)
((#\+) 0.33)
((#\-) -0.33)
(else 0))
0))))
不要忘记测试它:
(gpa-allocator 'A)
=> 4.0
(gpa-allocator 'A+)
=> 4.33
(gpa-allocator 'A-)
=> 3.67
答案 1 :(得分:1)
奥斯卡对于出了什么问题是正确的,但他的解决方案使用的是简单方案书中没有使用的功能。
这里是我从那本书中的那一章开始的解决方案
(define (gpa l-grades);;letter grades
(/ (accumulate + (every grade-value-mapper l-grades))
(count l-grades)
) )
(define (grade-value-mapper l-grade)
(let ((grade (first l-grade))
(g-mod (lambda (x)
(cond ((equal? '+ (bf l-grade))
(+ 1/3 x))
((equal? '- (bf l-grade))
(- 1/3 x))
(else x)
)) ) )
(cond ((equal? (first grade) 'a) (g-mod 4))
((equal? (first grade) 'b) (g-mod 3))
((equal? (first grade) 'c) (g-mod 2))
((equal? (first grade) 'd) (g-mod 1))
(else 0)
) ) )
不是我最好的工作,但希望它有所帮助。 gmod你可以进入它自己的定义。你会这样称呼它 ((gmod l-grade)4)
或拔出更多的瑕疵
((gmod l-grade)(字母值(第一个l级)))
我不认为(让......(等级......)......)确实做得很好。传递给grade-value-mapper的是单个等级。
您可以将输入清除器/检查器添加到函数grade-value-mapper中作为第一个cond子句。