0

我编写了一个从列表中获取每个值并返回每个值为 -1 的列表的过程(例如)

(define (Set-list a val)
  (if ( null? a) (list)
    (append (list val) (Set-list (cdr a) val))
))

(Set-list '(2 3 4) -1) //returns '(-1 -1 -1)
(Set-list '(A(2 3) B(2 3) C(2 3)) -1) // returns '(-1 -1 -1 -1 -1 -1)

我如何让它返回-1 -1 -1?我不想获取列表的内部成员?

4

4 回答 4

1

由于 Anton 提到了一个惯用的解决方案,这是我在 Racket 中的惯用解决方案(我相信使用高阶函数,如map,filter-not和可以说const比手动循环和过滤更惯用)。:-)

(define (set-list lst val)
  (map (const val) (filter-not list? lst)))

(Racket 确实提供filter-map了,但它以与我们想要做的相反的顺序应用filterand 。)map

于 2013-01-13T17:42:05.717 回答
1

也许您对列表在 Scheme 中的工作方式感到困惑。此列表:'(A(2 3) B(2 3) C(2 3))与此列表:完全相同'(A (2 3) B (2 3) C (2 3))。也就是说,它是一个六元素列表。如果要将符号和数字的组合视为单个元素,请将它们打包在一个列表中:'((A 2 3) (B 2 3) (C 2 3))

作为旁注,set-list编写过程的方式不是惯用的,特别append是在构建列表时使用不是将元素放在首位的最佳方式,请使用cons它。这是编写过程的更好方法:

(define (set-list a val)
  (if (null? a)
      '()
      (cons val
            (set-list (cdr a) val))))

现在,按照我上面的建议,它是如何工作的:

(set-list '((A 2 3) (B 2 3) (C 2 3)) -1)
=> '(-1 -1 -1)

更新:

现在,如果确实对列表的工作方式没有误解,并且您只想用给定值替换列表中的所有子列表,那么这将起作用:

(define (set-list a val)
  (build-list (length (filter (negate list?) a))
              (lambda (x) val)))
于 2013-01-13T16:17:54.123 回答
0

如果要创建一个长度与给定列表长度相同的值列表,

(define (set-list list value)
    (build-list (length list) (lambda (x) value)))

所以,

(set-list '(2 3 4) -1) //returns '(-1 -1 -1)
(set-list '(A (2 3) B (2 3) C (2 3)) -1) // returns '(-1 -1 -1 -1 -1 -1)
(set-list '(2 3 4) -2) //returns '(-2 -2 -2)
(set-list '(A (2 3) B (2 3) C (2 3)) -2) // returns '(-2 -2 -2 -2 -2 -2)
于 2013-02-02T02:15:24.203 回答
0

这是我的尝试(可能不是惯用的方案,请注意这样做append是错误的)。正如您在评论中解释的那样,我假设您想完全跳过子列表。

(define (Set-list a val)
  (if (null? a)
      (list)     
      (append (if (list? (car a))
                  (list)
                  (list val))
              (Set-list (cdr a) val))))
于 2013-01-13T16:25:51.417 回答