2013-01-19 128 views
1

我正在研究一个函数,该函数需要一个结构列表,然后使用该结构列表产生一个函数,将一个符号列表处理为一个数字。每个结构都由一个符号组成,这个符号将在第二个列表中被使用,并且是一个数字。生成的这个函数必须通过为每个符号分配一个基于先前结构的值来将符号列表变成一个数字。使用抽象列表函数btw。创建一个函数,生成一个函数方案/ DrRacket

Example: ((function (list (make-value 'value1 10) (make-value 'value2 20))) 
       (list 'value1 'value2 'nothing 'value1)) would produced 40. 

继承人我的代码,但它只适用于特定情况。

(define (function lst) 
    (lambda (x) (foldr + 0 (map (lambda (x) 
          (cond 
          [(equal? x (value-name(first lst)))(value-value (first lst))] 
          [else (value-value (second lst))])) 

          (filter (lambda (x) (member? x (map value-name lst)))x))))) 

回答

0

看起来像一个家庭作业。你的解决方案的基本形状是可以的。我认为你在这里遇到问题的原因是你的代码没有分解,所以在括号中很容易丢失。

让我们从fold的想法开始,+作为最后一步的计算。

对于这个子任务,你必须:

1)的(名称,值)对 2)名称

列表的服务,您需要获得值的列表。编写一个独立的函数,完成并使用它。像这样

(define (function lst) 
    (lambda (x) (foldr + 
         0 
         (to-values x lst))) 

(define (to-values names names-to-values) 
    (map (lambda (name) 
      (to-value name names-to-values)))) 

(define (to-value n ns-to-vs) 
    ...) 

在这里,我们有另一个小功能mapnames。它会查找ns-to-vs中的n值,并返回它或0,如果没有人。

+0

如何编写最后一个函数,我仍然遇到我的同一问题 – user1992460

+0

提示:https://www.google.com/search?q=racket+findf – hoha

+0

无法使用findf – user1992460

0

有两种解决foldr问题的方法,研究和理解这两种方法会很有趣。第一个尝试在问题中,首先是生成一个包含所有值的列表,并让foldr负责添加它们。它能够以更简单的方式来实现这样的:

(define (function lst) 
    (lambda (x) 
    (foldr + 
      0 
      (map (lambda (e) 
        (cond ((assoc e lst) => value-value) 
         (else 0))) 
       x)))) 

或者:也许使用foldr是矫枉过正,应用+简单:

(define (function lst) 
    (lambda (x) 
    (apply + 
      (map (lambda (e) 
        (cond ((assoc e lst) => value-value) 
         (else 0))) 
       x)))) 

在我们把输入列表“因为是第二种方法“并让foldrlambda执行加法逻辑。这比使用foldr第一种方法更有效,因为没有必要创建一个中间表 - 一个在第一个版本由map产生:

(define (function lst) 
    (lambda (x) 
    (foldr (lambda (e a) 
      (cond ((assoc e lst) => (lambda (p) (+ a (value-value p)))) 
        (else a))) 
      0 
      x))) 

在这两种方法我使用assoc寻找元素在列表中;如果不允许使用它,或者它不适用于使用make-valueassoc创建的值,它将很容易实现为帮助器函数,它会获取名称 - 值对列表并返回具有给定名称的第一个对。 语法condassoc返回的对传递给lambda的参数并执行它。

而且由于你使用的球拍,还有的语法糖位,可用于从另一个函数返回一个函数,试试这个等效的代码,为了简单起见:

(define ((function lst) x) 
    (foldr + 
     0 
     (map (lambda (e) 
       (cond ((assoc e lst) => value-value) 
         (else 0))) 
       x))) 

还是这个:

(define ((function lst) x) 
    (foldr (lambda (e a) 
      (cond ((assoc e lst) => (lambda (p) (+ a (value-value p)))) 
       (else a))) 
     0 
     x)) 

无论如何,如预期的结果:

((function (list (make-value 'value1 10) (make-value 'value2 20))) 
(list 'value1 'value2 'nothing 'value1)) 
=> 40 
相关问题