微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在方案中运行嵌套的for循环

如何解决如何在方案中运行嵌套的for循环

我正在研究如何将此伪代码转换为惯用方案:

for c in range(1,1000):
    for b in range(1,c):
        for a in range(1,b):
            do something if condition is true

解决方法

在Scheme中表达任何种类的循环(实际上是更通用的控制结构)非常容易。例如,如果您想要一个简单的循环,可以这样做:

(let loop ([i 0])
  (if (>= i 10)
      (values)
      (begin
        (display i)
        (loop (+ i 1)))))

您显然可以嵌套这些。

但是,比起用Python编写的代码,它不那么易读:

for i in range(10):
    print(i)

好的,好的。但是Lisp家族语言是关于建筑语言的 :如果所需的语法不存在,则可以使它存在。。这是执行此操作的示例:

(define-syntax nloop*
  ;; Nested numerical loop
  (syntax-rules ()
    [(_ () form ...)
     (begin form ...
            (values))]
    [(_ ((variable lower-inclusive upper-exclusive) more ...) form ...)
     (let loop ([variable lower-inclusive])
       (if (< variable upper-exclusive)
           (begin
             (nloop* (more ...) form ...)
             (loop (+ variable 1)))
           (values)))]
    [(_ ((variable start-inclusive end-exclusive step) more ...) form ...)
     (let ([cmp? (if (>= step 0) < >)])
       (let loop ([variable start-inclusive])
         (if (cmp? variable end-exclusive)
             (begin
               (nloop* (more ...) form ...)
               (loop (+ variable step)))
             (values))))]))

现在:

> (nloop* ((i 0 10))
    (print i))
0123456789

而且

> (nloop* ((i 0 10)
           (j 20 0 -4))
    (displayln (list i j)))
(0 20)
(0 16)
(0 12)
(0 8)
(0 4)
...
(9 20)
(9 16)
(9 12)
(9 8)
(9 4)

因此,我刚刚发明的nloop*构造将完成包括嵌套循环在内的完全通用的数字循环(这就是*nloop(不存在)将循环的原因。平行)。

当然,在诸如Racket之类的工业强度方案派生的语言中,已经有执行此操作的结构:

(for ([i (in-range 10)])
  (for ([j (in-range 20 0 -4)])
    (displayln (list i j))))

将是惯用的Racket方法。但是for及其所有变体和基础结构仅仅是语言构造,您原则上可以在一个非常简单的方案中编写您自己

这些语言是为建筑语言设计的。

,

您的伪代码可以作为嵌套的命名let序列直接转换为Scheme,就像

(let loopc ((c 1))                ; start the top loop with c = 1,(if (> c 1000)                  ; if `c > 1000`,#f                            ;   exit the top loop ; or else,(let loopb ((b 1))            ; start the first-nested loop with b = 1,(if (> b c)                 ; if `b > c`,(loopc (+ c 1))           ;   end the first-nested loop,and
                                  ;   continue the top loop with c := c+1 ; or else,(let loopa ((a 1))        ; start the second-nested loop with a = 1,(if (> a b)             ; if `a > b`,(loopb (+ b 1))       ;   end the second-nested loop,and
                                  ;   continue the first-nested loop with b := b+1
            (begin                ; or else,(if condition       ;   if condition holds,(do_some a b c)   ;     do something with a,b,c,#f)               ;   and then,(loopa (+ a 1))     ;   continue the second-nested loop with a := a+1
              )))))))

当然,这有点涉及并且容易出错。另一方面,通过从{{1}内部调用a可以很容易地缩短最内部的循环(在c上并直接重新启动最上面的循环(在loopc上)。 }(始终处于 tail位置,NB!)。

例如,上面的代码直接适用于您在注释中陈述的问题,即找到总计为1000的勾股三联体。此外,当您找到解决方案时,可以直接调用{{1 }}立即退出整个三重嵌套循环结构。


作为旁注,

loopa

不是最有效的解决方案。至少首先是

(loopc 1001)

此外,

for c in range(3,1000):
    for b in range(2,c):
        for a in range(1,b):
            if a**2 + b**2 == c**2 and a + b + c == 1000:
                print(a * b * c)
,

有许多难以置信的方法来解决您的问题。这是我现在想到的最简单的方法:

(define iota
  (lambda (n k)
    ((lambda (s) (s s 1))
     (lambda (s x)
       (k x)
       (or (= n x)
           (s s (+ x 1)))))))

(iota 1000
      (lambda (c)
        (iota c
              (lambda (b)
                (iota b
                      (lambda (a)
                        (newline)
                        (display a) (display " ")
                        (display b) (display " ")
                        (display c) (display " ")))))))

如果c的初始间隔是1..3而不是1..1000,则嵌套代码将包含以下(a b c)值:

a b c
1 1 1
1 1 2
1 2 2
2 2 2
1 1 3
1 2 3
2 2 3
1 3 3
2 3 3
3 3 3

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?