【问题标题】:Complex Loop Optimization复杂循环优化
【发布时间】:2015-11-04 23:52:57
【问题描述】:

我有一个函数,它接受一个状态和一个动作,并返回一个新状态,该状态是在原始状态下应用接收到的动作产生的。

我的问题是我编写了一个复杂的 loop 代码,我想对其进行优化,以便它为我带来更清晰的阅读功能和更优化的功能。

我有这个复杂的“伪代码” loop 部分函数源:

(loop for l from 0 upto (1- (array-dimension variable1 0)) do
  (if (not (aref variable1 l 0))
    (1+ max-height)
    (return)))

我有什么机会让loop 更简单和优化?

Loop DocumentationDoTimes Documentation 在我看来不够清楚,无法对我的代码进行更改,对此我深表歉意。任何解释都会对我有价值。

【问题讨论】:

  • 我敢打赌,sn-p 无论如何都不起作用。它究竟应该做什么?
  • 该循环假设使 俄罗斯方块游戏 中的一行被递减,这样对象就会下降,以防它在第一列中有 NIL 元素。
  • decf 应该修改一个地方。我不确定 array-dimension 是否是您应该尝试修改的地方。函数 1- 可能就是您要在那里寻找的。​​span>
  • 代码sn-p有多个错误。这没有任何意义。
  • @JoshuaTaylor 你是对的,代码是一个不干净和错误的例子。我做了我的改变,谢谢。

标签: lisp common-lisp


【解决方案1】:

您的原始代码可能有一些错误,因为存在语法问题,没有使用正确数量的参数调用数组维度等,但是您的循环很容易变成一个 dotimes。应该是这样的(但请注意,您需要检查是否要引用数组或对象):

(dotimes (i (array-dimension array 0))  ; array here
  (unless (aref object i 0)             ; but object here?
    (decf max-height)))

根据对问题的更新,我认为我们可以稍微改进一下。从代码中,我们可以看出您希望有一个(广义)布尔值的二维数组,并且您正在尝试计算第一列中的真实元素。下面是这样一个板的外观:

(defparameter *board* #2A((nil t nil)
                          (t t t)
                          (t t t)))

注意第一行有一个真值,第一列有两个真值。现在,您可以编写一个 dotimes 循环来计算第一列中真值的数量,如下所示:

(let ((max-height 0))
  (dotimes (i (array-dimension *board* 0) max-height)
    (when (aref *board* i 0)
      (incf max-height))))
;=> 2

但是,我认为 loop 在这里实际上更干净,如果您利用它的一些功能。您可以使用 below 代替 upto,并且 from 默认为 0,因此您可以省略它。可以使用count来统计真值,然后默认返回count的值:

(loop for i below (array-dimension *board* 0)
   count (aref *board* i 0))
;=> 2

【讨论】:

  • 如您所见,我已经更新了我的示例@JoshuaTaylor,使其更加清晰并使用正确的代码。如果你愿意,你可以用这种方式改变你的。谢谢。
  • @FranciscoMariaCalisto 查看我的编辑。我认为你实际上可以使用循环比使用 dotime 更简洁,但我已经为两者提供了更新解决方案。
  • 太棒了!谢谢@JoshuaTaylor。但是,您说的“未使用正确数量的参数调用数组维度”已经在正确的形式上。
  • @FranciscoMariaCalisto 我不确定你最后的评论是什么意思。我发布的更新中的代码运行并产生了我展示的输出。 array-dimension 需要两个参数:数组和所需维度的轴。
  • @FranciscoMariaCalisto 是的,现在可以了,但是我说它被错误数量的参数调用的答案部分是基于你的 original 代码已发布,其中包括 (array-dimension 0),其参数数量错误。一般来说,更改问题中的代码并不是一个好主意,因为(正如我们所见)它会使解决原始版本中问题的答案无效,并使评论讨论变得混乱。这也使问题更难回答,因为它变成了一个移动的目标。
猜你喜欢
  • 2018-05-09
  • 2012-03-10
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 2017-07-20
相关资源
最近更新 更多