返回函数内部包含 1 个元素的新创建列表

Returning newly created list with 1 element inside function

我目前正在构建一个 return 一行帕斯卡三角形的函数。我的函数传入一个列表,其中包含 Pascal 三角形中的一行和 return 下一行,具体取决于传入的行。 前任。传入 '(1 2 1),它应该 return '(1 3 3 1)。 但是我似乎无法在列表中找到开头的 1。

(define build-next
   (lambda(thisRow)
      (cond
         [(null? thisRow) '(1)]
         [(null? (cdr thisRow)) (cons 1 (cdr thisRow))]
         [else (cons (+ (car thisRow) (car (cdr thisRow))) (build-next(cdr thisRow)))])))

(build-next '(1 2 1))

运行 这段代码会给我输出

'(3 3 1)

没有前导 1

这是一个可能的解决方案:

(define build-next
  (lambda(thisRow)
    (define helper-build-next
      (lambda (lst prev)
        (if (null? lst)
            (list prev)
            (cons (+ prev (car lst)) (helper-build-next (cdr lst) (car lst))))))
    (if (null? thisRow)
        (list 1)
        (cons (car thisRow) (helper-build-next (cdr thisRow) (car thisRow))))))

递归是通过辅助函数执行的,该函数获取行的其余部分和行的前一个元素。最初函数检查参数是否为空列表,以便返回三角形的第一行。否则,将使用初始参数调用辅助函数。

也可以使用命名let来写build-next如下:

(define (build-next row)
  (let loop ([row row]
             [acc 0])
    (cond
      [(zero? acc)
       (cons 1 (loop row (add1 acc)))]
      [(null? row) empty]
      [(null? (cdr row)) (list 1)]
      [else
       (cons (+ (car row) (cadr row))
             (loop (cdr row) acc))])))

循环参数acc用作累加器,在下一行(即第一个cond case)中添加前导1。

例如,

(build-next '())                 ;;=> '(1)
(build-next '(1))                ;;=> '(1 1)
(build-next '(1 1))              ;;=> '(1 2 1)
(build-next '(1 2 1))            ;;=> '(1 3 3 1)
(build-next '(1 3 3 1))          ;;=> '(1 4 6 4 1)
(build-next '(1 4 6 4 1))        ;;=> '(1 5 10 10 5 1)

如果输入行的第一个元素为零,则您的函数有效。 将您的原始函数重命名为 build-next-helper 并引入 一个新的 build-next 在前缀零之后简单地调用你现有的函数工作正常:

(define build-next-helper
  (lambda (thisRow)
    (cond
      [(null? thisRow)      '(1)]
      [(null? (cdr thisRow)) (cons 1 (cdr thisRow))]
      [else                  (cons (+ (car thisRow) (car (cdr thisRow)))
                                   (build-next-helper (cdr thisRow)))])))

(define (build-next thisRow)
  (build-next-helper (cons 0 thisRow)))

(build-next '(1 2 1))