3
(define (orderedTriples n)
(set! i n)
(set! j n)
(set! k n)
(while (>= i 0)
   (while (>= j 0)
     (while (>= k 0)
       (printf "(~a, ~a, ~a)" i j k) 
       (set! k (- k 1))) 
     (set! j (- j 1))) 
  (set! i (- i 1))))

所以我的问题是......我对如何使 while 循环在方案中工作感到困惑(我对此很陌生,所以如果我离开了,请原谅语法)。我在这里输入 while 只是为了解决问题并展示我想要完成的工作。谁能帮我一个简单的递归示例或嵌套递归?

4

3 回答 3

5

根据使用的 Scheme 解释器,有几种方法可以实现所需的循环。例如,在 Racket 中,它就像使用迭代和推导一样简单:

(define (orderedTriples n)
  (for* ([i (in-range n -1 -1)]
         [j (in-range n -1 -1)]
         [k (in-range n -1 -1)])
    (printf "(~a, ~a, ~a)" i j k)))

问题中显示的编程风格(假设它有效)在Scheme中非常不鼓励 - 使用突变(set!操作)进行循环是一个很大的禁忌,这就是你用类C语言解决问题的方式,但是特别是在 Scheme 中(以及在一般的 Lisp 中)还有其他用于在程序中实现迭代的构造(do例如,@TerjeD 给出的解决方案演示了 的使用),即使这样的构造不存在,递归解决方案或者使用更高阶程序的解决方案将是首选。例如,这是另一种可能的解决方案,使用仅具有标准过程的嵌套映射(除了printf,它是非标准的):

(define (range n)
  (if (negative? n)
      '()
      (cons n (range (- n 1)))))

(define (orderedTriples n)
  (for-each (lambda (i)
              (for-each (lambda (j)
                          (for-each (lambda (k)
                                      (printf "(~a, ~a, ~a)" i j k))
                                    (range n)))
                        (range n)))
            (range n)))
于 2013-02-03T23:24:57.320 回答
2

您可以使用do这样编写的循环(用于函数的内部循环):

(do ((k n (- k 1)))               ; variable, initialization, and updating form
   ((< k 0))                      ; stop condition, and optionally return value
  (printf "(~a, ~a, ~a)" i j k))  ; body forms

有关迭代构造的更多信息,请参见http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-ZH-7.html#%_idx_138 。do

于 2013-02-03T23:03:10.957 回答
1

如果必须,您可以使用递归来做到这一点。

(define (ordered-triples n)
  (let iloop ((i n))
    (unless (negative? i)
      (let jloop ((j n))
        (unless (negative? j)
          (let kloop ((k n))
            (unless (negative? k)
              (printf "~a ~a ~a\n" i j k)
              (kloop (sub1 k))))
          (jloop (sub1 j))))
      (iloop (sub1 i)))))

当然,使用 Racket 的for*循环更容易。

于 2013-02-04T10:01:47.937 回答