首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在LispWorks中嵌套for-循环(4x4皇后)

在LispWorks中嵌套for-循环(4x4皇后)
EN

Stack Overflow用户
提问于 2015-09-13 07:35:53
回答 1查看 250关注 0票数 1

我刚刚开始使用LispWorks,我正在研究4x4Queen问题。我想要做的是在4个循环的帮助下,声明所有可能的皇后组合,然后检查它们是否是可能的解决方案。例如,可能的状态( 1,3,4,2)意味着,在第1行,皇后在第1列,在第2行,皇后在第3列,等等。

不过,我认为我做错了什么,因为编译器不喜欢我的循环。我得到的错误是:循环关键字在.

以下是代码:

代码语言:javascript
复制
(loop for i in '(1 2 3 4) 
  nconc (loop for j in '(1 2 3 4) 
              nconc (loop for k in '(1 2 3 4) 
                          nconc (loop for l in '(1 2 3 4) 


                                     (defvar first 0)
                                     (defvar second 0)
                                     (defvar third 0)
                                     (defvar fourth 0)
                                     (setq first (abs (- 1 i)))
                                     (setq second (abs (- 2 j)))
                                     (setq third (abs (- 3 k)))
                                     (setq fourth (abs (- 4 l)))
                                     (if (and (not (eq first second)) (not (eq first third)) (not (eq first fourth)) (not (eq second third)) 
                                                (not (eq second fourth)) (not (eq first second)) (not (eq third fourth)))
                                           (if (and (or (eq i j) (eq i k) (eq i l) (eq j k) (eq j l)) (or (eq k l)))
                                               (print i j k l)))))))

请帮助我解决嵌套循环,并随时评论我的代码,并可能建议更好的方法来解决这个问题。请保持它相当基本,我是一个完全初学者的LispWorks,我只做了一些ADA 95和Java之前。

提前谢谢你

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-13 14:34:21

获得错误消息的原因是,在内环中的do之后,您的代码缺少关键字'(1 2 3 4)。由于您不是从循环中收集结果,而只是打印最终结果,所以应该在外部循环中使用do而不是nconc

修复此问题,会出现另一个错误:print只打印一个对象,因此为了打印所有四个数字,可以使用(print (list i j k l))

然后程序打印

代码语言:javascript
复制
(1 1 1 1) 
(1 3 1 1) 
(2 2 1 1) 
(4 2 2 2) 
(4 4 3 3) 
(4 4 4 4)

所以逻辑也有问题。

但是,还可以对代码进行许多改进:

  1. 不要使用defvar在循环中引入新变量。defvar创建动态(“全局”)变量。相反,使用let,或者将它们作为循环变量引入,就像您对ij等所做的那样。
  2. 与其首先创建变量,然后使用setq更新它们,不如在创建变量时给它们正确的值(使用let或循环关键字)。
  3. 当您比较数字对时:而不是使用eq (用于符号)或eql (这是比较相同类型的两个数字的正确方法),而是使用=/=来比较多个数字,以检查它们是否都相等/不同。

连同对逻辑的小修正,这将产生以下代码(为了举例说明,代码引入了一些使用循环关键字的变量,还有一些使用了let):

代码语言:javascript
复制
(loop for i in '(1 2 3 4) 
      for first = (abs (- 1 i)) 
      do (loop for j in '(1 2 3 4)
               for second = (abs (- 2 j))
               do (loop for k in '(1 2 3 4)
                        do (loop for l in '(1 2 3 4)
                                 do (let ((third (abs (- 3 k)))
                                           (fourth (abs (- 4 l))))
                                       (if (and (/= first second third fourth)
                                                (/= i j k l))
                                          (print (list i j k l))))))))

会导致

代码语言:javascript
复制
(2 4 3 1) 
(3 2 4 1) 
(4 1 3 2) 
(4 2 1 3) 

这意味着仍然存在逻辑错误。

希望通过简化的代码可以很容易地发现错误,这可能与不比较(+ i 1)(+ j 2)等有关。

最后:如果您想扩展代码以处理更多的皇后,创建递归解决方案将比使用更多嵌套循环的解决方案更好。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32547383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档