从条件的循环中返回

问题描述 投票:0回答:1

我有以下函数。

(defun chooseBest (TSPs dTSPs)
    (let ((minim (minPos dTSPs 0 0)) (j 0) (best nil)) 
        (loop for i in TSPs
             do (cond ((= j minim) (progn (setf best i) (setq j (+ j 1))))
                      (t (setq j (+ j 1)))))        
        best))

这个函数接收两个列表:

TSPs -- 一个像这样的路径列表:

(((1 3600 2300) (2 3100 3300))
 ((3 4700 5750) (22 6650 2300) (23 5400 1600)))

和一个与这些路径相关的距离列表。

(distancePath1 distancePath2)

这个函数 minPos 返回列表中距离较小的路径的位置。

既然如此,那么 chooseBest 函数将返回较小的路径。

但我想改进它,因为它会搜索整个列表中的小数,这是一种浪费,因为这个 minim 拥有该职位。例如 minim 是2,但是它正在评估一个有100条路径的TSPs列表,我想在2的时候立即返回,然后中断循环,但是返回不起作用......。

lisp common-lisp
1个回答
3
投票

让我们重做一下你的函数。

首先,用更好的 缩进:

(defun chooseBest (TSPs dTSPs)
  (let ((minim (minPos dTSPs 0 0))
        (j 0)
        (best nil))
    (loop for i in TSPs
       do (cond ((= j minim)
                 (progn (setf best i)
                        (setq j (+ j 1))))
                (t 
                 (setq j (+ j 1)))))
    best))

不需要 progn 里面 cond:

       do (cond ((= j minim)
                 (setf best i)
                 (setq j (+ j 1)))
                (t 
                 (setq j (+ j 1)))))

递增j 得以 incf:

                 (setq j (+ j 1)))

=>

                 (incf j)

你可以移动 让变量 进入 .

  (let ((minim (minPos dTSPs 0 0))
        (j 0)
        (best nil))
    (loop for i in TSPs

=>

(loop for it in TSPs
      for j from 0
      with minim = (minPos dTSPs 0 0)
      with best
      do …)

for j from 0 启动一个计数器。with … = 声明一个在开始时计算的变量(而不是在每次迭代时)。

返回和条件

在一个循环中,我们可以使用 if…do, else…do, whenreturn,而且不止一次。 要在循环的最后做一些事情,使用 finally.

(defun chooseBest (TSPs dTSPs)
  (loop for i in TSPs
     for j from 0
     with minim = (minPos dTSPs 0 0)
     with best
     if (= j minim)
     do (progn (setf best i)
               (incf j))
     else
     do (incf j)
     finally (return best)))

搜索列表和序列的功能

如果你想在一个列表中找到一个元素,你有很多函数可以实现:find, nth, search, position,......见。https:/lispcookbook.github.iocl-cookbookdata-structures.html#functions。minPos 返回一个索引,你可能需要 nth index listelt sequence index.


0
投票

如果你想要 第十 元素,你可以使用函数 nth: (nth position list)

CL-USER 15 > (nth 0 '(((1 3600 2300) (2 3100 3300))
                      ((3 4700 5750) (22 6650 2300) (23 5400 1600))))
((1 3600 2300) (2 3100 3300))

CL-USER 16 > (nth 1 '(((1 3600 2300) (2 3100 3300))
                      ((3 4700 5750) (22 6650 2300) (23 5400 1600))))
((3 4700 5750) (22 6650 2300) (23 5400 1600))

如果你想从循环中返回,你可以使用操作符。return:

CL-USER > (loop for i from 10
                when (= i (expt (isqrt i) 2))
                do (return i))
16
© www.soinside.com 2019 - 2024. All rights reserved.