Lisp 简单的计划。第08章。更高—;序函数

Lisp 简单的计划。第08章。更高—;序函数,lisp,scheme,Lisp,Scheme,问候 总结 无法将'(+)或'(-)作为数据传递给cond(未计算)。它们自己返回(+)或(-),作为参数返回标识元素(0) 救命啊 背景。 对于规范中的非标准方案 在这本书中; 句子是简单的列表和句子 单词是sybmol和字符串。 simply.scm中有三个高阶函数/过程,部分用于说明主题、每个、保持和累积 (每个函数数据)[对每个数据元素执行此函数] (保留谓词?数据)[保留通过谓词?测试的数据元素] (累积功能数据)[将所有数据收集到功能的形式中-与keep结合以删除无效数据] 例如(累

问候

总结

无法将'(+)或'(-)作为数据传递给cond(未计算)。它们自己返回(+)或(-),作为参数返回标识元素(0)

救命啊

背景。 对于规范中的非标准方案

在这本书中; 句子是简单的列表和句子 单词是sybmol和字符串。 simply.scm中有三个高阶函数/过程,部分用于说明主题、每个、保持和累积

  • (每个函数数据)[对每个数据元素执行此函数]
  • (保留谓词?数据)[保留通过谓词?测试的数据元素]
  • (累积功能数据)[将所有数据收集到功能的形式中-与keep结合以删除无效数据] 例如(累积+(保留数字?数据))[删除非数字,然后将其余数字相加,如果未找到数字,则为零]
  • 数据流。 练习是一个gpa计算器程序。根据指令,不允许lambda或递归(如果按顺序读取,则尚未设定)

    我尝试的第一个实现在一个句子中包含多个等级,并输出单独的句子,每个句子都有一个等级。然后,它将此输出传递给助手过程

    如果单级输出有一个+或-将其分离,例如“(a+)分为“(a”)和“(+),然后将所有输出传递给另一个帮助程序

    然后一个cond分配分数

    a 4
    b 3
    c 2
    d 1
    e 0
    + 0.33
    - -0.33
    
    这只在我的头脑中起作用(为什么计算机不能像大脑一样工作?)当一个等级像“(a+)或“(a-)被分开时,”(a)被正确处理,但“(+)或“(-)计算到身份元素(0)中,并且无法添加到gpa中

    有没有办法使“(+)”和“(-)可以作为数据而不是表达式通过?或者,在它们返回(0)之前,我可以将它们转换为在cond中可用的任意数据吗

    目前的版本,每个等级都有一个很长的cond,有效,但很可怕。使实现感觉像是命令式的,而不是函数式编程

    代码。 返回错误的gpa(不添加0.33或-0.33): 此外,输入类型签入(gpa助手)也失败得惊人

    (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) )
    
    (定义(gpa成绩集)
    (/(累计+(每个gpa辅助成绩集))(计数成绩集)))
    (定义(gpa辅助等级)
    (条件((或(<(计分分数)1)(>(计分分数)2))(请使用有效的分数输入)
    (=(计数成绩)1)(gpa分配器(保持有效成绩?成绩)))
    (=(计算成绩)2)(每个gpa助手(保持有效成绩?成绩)))
    (否则(请检查输入的所有成绩是否有效)))
    (定义(gpa分配器等级字母+-)
    (第二个((相等?成绩字母+-'a)4)
    ((等分字母+-'b)3)
    ((等分字母+-'c)2)
    ((等分字母+-'d)1)
    ((等分字母+-'e)0)
    ((等分字母+-+).33)
    ((等分字母+-)(.33))
    (其他(0)))
    (定义(有效等级?等级输入)
    (如果(成员等级为“(+-a+a-b+b-c+c-d+d-e))#t#f))
    
    重做版本,返回单个分数的句子。由“(+)”和“(-)返回的0在此处可见。实现了成功的输入类型检查,但引入了新问题。(将结果累加一次)

    (定义(gpa成绩集)
    (每个gpa清洁等级集)
    (定义(gpa清洁剂等级)
    (条件((或(<(计数分级)1)(>(计数分级)2))0)
    (其他(每个gpa累加器等级均为WRD)))
    (定义(gpa累加器等级WRD)
    (/(累计+(每个gpa助手成绩))(计数成绩)))
    (定义(gpa辅助等级)
    (条件((=(计数成绩)1)(gpa分配器(保持有效成绩?成绩)))
    (=(计算成绩)2)(每个gpa助手(保持有效成绩?成绩)))
    (否则(请检查输入的所有成绩是否有效)))
    (定义(gpa分配器等级字母+-)
    (第二个((相等?成绩字母+-'a)4)
    ((等分字母+-'b)3)
    ((等分字母+-'c)2)
    ((等分字母+-'d)1)
    ((等分字母+-'e)0)
    ((等分字母+-+).33)
    ((等分字母+-)(.33))
    (其他(0)))
    (定义(有效等级?等级输入)
    (如果(成员等级为“(+-AB c d e))#t#f))
    

    使用带Slib 3b3的SCM版本5e7、随Simply Scheme提供的附加库(在上面的背景下提供的链接-Simply.SCM、functions.SCM、ttt.SCM、match.SCM、database.SCM)以及我为每个加载的练习输入答案的库。

    如果需要将
    +
    -
    作为符号传递(不是作为程序),您必须首先引用:

    '+
    '-
    
    例如:

    ((equal? gradeletter+- '+) .33)
    ((equal? gradeletter+- '-) -.33)
    
    但是从上下文来看,我不认为
    gpa分配器
    过程是正确的。成绩可以是
    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
    

    Oscar对错误的判断是正确的,但他的解决方案使用了simply scheme手册中未使用的函数

    这是我读那本书那一章时的解决办法

    (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级)4)

    或者拔出更多的磨损

    ((gmod)
    (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)
     )   )   )