我有2个数字,我们说number1 = 5,number2 = 3,我想以这种形式创建一个列表
(p(1(1 2 3))(2(1 2 3))(3(1 2 3))(4(1 2 3))(5(1 2 3)))因此number1表示列表中元素的数量,number2表示将作为每个元素的第二部分的总元素。
我现在已经这样了,直到现在
(define mylist '())
(define (pushlist item item2)
(do ((j 1 (+ j 1))) ((> j item2))
(set! mylist(list mylist (list item j)))))
(define (createlist number number2)
(do ((j 1 (+ j 1))) ((> j number))
(pushlist j number2)
))
(createlist 5 3)
不幸的是它不起作用..它没有给出我想要的结果..它给了我(((((((((((((((() (1 1)) (1 2)) (1 3)) (2 1)) (2 2)) (2 3)) (3 1)) (3 2)) (3 3)) (4 1)) (4 2)) (4 3)) (5 1)) (5 2)) (5 3))
答案 0 :(得分:1)
有许多方法可以解决此问题 - 例如,使用显式递归或使用高阶过程。不推荐您的方法,在Scheme中,您应该尽量避免考虑循环和变异操作。虽然 可以编写这样的解决方案,但它不会是惯用的。我将首先尝试使用显式递归来解释如何编写更惯用的解决方案:
; create a list from i to n
(define (makelist i n)
(if (> i n)
'()
(cons i (makelist (add1 i) n))))
; create a list from i to m, together with
; a list returned by makelist from 1 to n
(define (makenumlist i m n)
(if (> i m)
'()
(cons (list i (makelist 1 n))
(makenumlist (add1 i) m n))))
; call previous functions
(define (createlist number1 number2)
(makenumlist 1 number1 number2))
现在,一个更惯用的解决方案是使用更高阶的程序。这将适用于Racket:
; create a list from i to n
(define (makelist n)
(build-list n add1))
; create a list from i to m, together with
; a list returned by makelist from 1 to n
(define (makenumlist m n)
(build-list m
(lambda (i)
(list (add1 i) (makelist n)))))
; call previous functions
(define (createlist number1 number2)
(makenumlist number1 number2))
了解我们如何避免显式循环?这就是计划的思维方式,你期望解决问题的方式 - 拥抱它!
答案 1 :(得分:0)
我不认为您的pushlist
程序正在按照您的预期行事。
(define (pushlist item item2)
(do ((j 1 (+ j 1)))
((> j item2))
(set! mylist (list mylist (list item j)))))
如果您有一个列表(x y z)
,并且想要将新值v
添加到其中,则可以
(set! lst (cons v lst))
因为(cons v (x y z)) == (v x y z)
。通过做
(set! mylist (list mylist (list item j)))
你正在使mylist
总是有两个元素,其中第一个是更深入和更深的嵌套列表。 Óscar López's answer为这个问题提供了更为惯用的方法。这是一种类似的惯用法:
(define (range n)
; returns a list (1 ... n)
(let rng ((n n) (l '()))
(if (zero? n)
l
(rng (- n 1) (cons n l)))))
如果子列表(1 ... n)
都可以是相同的列表(即实际列表对象是相同的),那么您只需创建一次:
(define (createlist m n)
(let ((sublist (range n)))
(map (lambda (main)
(list main sublist))
(range m))))
否则,如果需要区分,则可以为1 ... m
生成一个:
(define (createlist m n)
(map (lambda (main)
(list main (range n)))
(range m)))