返回函数内部包含 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))
我目前正在构建一个 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))