2

我已经被这个困扰了好几天了。这是我正在尝试做的事情:

假设我有一些符号列表。例如。'(A B C D)。我想将这些符号映射到值。假设我的价值观是'(1 2 3 4)。

好的,现在这是目标。我想编写一个过程,该过程将返回一个我以后可以再次调用的过程。这就是我的意思:

(定义获取映射值(映射在一起的符号值))

(获取映射值'A)

应该返回'1。

到目前为止,我已经编写了一个程序来获取两个列表并将它们“压缩”在一起,基本上是映射值。所以给定 '(ABCD) 和 '(1 2 3 4) 它将返回 ((A 1)(B 2)(C 3) 等等。

而且我还写了一个程序,给定一个符号将返回它的映射值。但我很难把这一切联系起来并做出这个定义。我最近的尝试是:

(define map-together
  (case-lambda
    [(symbols vals) (lambda (cons lst (zip-together keys vals))]
    [(symbol) (find-mapped-value symbol)]
       
      )
    )
  )

但这只是返回压缩列表。

4

3 回答 3

2

该解决方案比您想象的要简单一些 - 只要find-mapped-value正确实施,这应该可以工作:

(define (map-together keys vals)
  (let ((alist (zip-together keys vals)))
    (lambda (key)
      (find-mapped-value key alist))))

说明:首先,使用 . 创建一个关联列表(称为alistzip-together。该列表对于所有搜索都是相同的,因此我们可以将它包含在返回的过程之外。

之后,返回一个处理在关联列表中查找键的过程,注意我修改find-mapped-value了 - 现在它接收到搜索键和关联列表。

只是为了好玩,解决这个问题的另一种方法是使用assoc,因为该过程已经执行了find-mapped-value. 这是我对解决方案的看法:

(define (map-together keys vals)
  (let ((alist (map list keys vals)))     ; same as zip-together
    (lambda (key)
      (cond ((assoc key alist) => second) ; similar to find-mapped-value
            (else #f)))))

当然,对于大型列表,更有效的解决方案是使用哈希表:

(define (map-together keys vals)
  (let ((mapping (make-hash (map cons keys vals))))
    (lambda (key)
      (hash-ref mapping key (const #f)))))

所有上述实现都按预期工作,如果映射中不存在密钥,它们将返回#f

(define symbols '(A B C D))
(define  values '(1 2 3 4))
(define get-mapped-value (map-together symbols values))

(get-mapped-value 'A)
=> 1

(get-mapped-value 'F)
=> #f
于 2013-09-13T01:15:19.910 回答
0

这将是接近。

(define (map-together)
  (let ((a-list '()))
    (case-lambda
      [(symbols vals) 
       (begin (set! a-list (cons lst (zip-together keys vals)))
              a-list)]
      [(symbol) (find-mapped-value symbol)])))

无论如何,局部变量应该有所帮助。你会这样使用它

(定义字母值(映射在一起))

(字母值 (list 'a 'b 'c 'c) (list 1 2 3 4))

(字母值'c)-> 3

不确定它是否正是你想要的。对于较大的值,您可能希望使用哈希表或红黑树而不是关联列表。Racket 应该在某处的模块中实现两者。

如果您使用 (symbols vals) 调用此函数,该函数将覆盖旧的 a-list。如果你想要一些可以附加和更新你的列表的东西,它会变得有点棘手。

于 2013-09-13T01:18:13.400 回答
0

您的map-together函数需要返回一个接受符号并返回值的函数。返回的值将基于将符号映射到值的表。像这样:

(define (map-together symbols values)
  (let ((table (map cons symbols values)))
    (lambda (symbol)
      (cond ((assq symbol table) => cdr)
            (else #f)))))

> (define get-mapped-value (map-together '(a b c d) '(1 2 3 4)))
> (get-mapped-value 'a)
1

从符号到值的映射通过使用(map cons symbols values). 使用该关联列表,我们可以使用在关联assq中查找pair;如果存在这样的一对,cdr则为值。

请注意,由于表没有改变,我们根据table我们在lambda.

于 2013-09-13T17:29:24.690 回答