2015-06-03 18 views
0

我试着写了“最近”的功能,在Lisp中,不使用setq/SETF等等LISP - 没有setq最近的功能/ SETF等

函数发现一个给定的向量的最近邻的矢量(在列表中找到它)。

我试过了,但没有套太硬,非常感谢。

回答

1

通常变量的更新是通过递归方法来实现:

(defun main-function (arg) 
    (main-function-helper arg 0 1)) 

(defun main-function-helper (arg var1 var2) 
    (if (= arg var1) 
     var2 
     (main-function-helper arg (1+ var1) (1+ var2)))) 

当你做,你可以把助手进入主功能:

(defun main-function (arg) 
    (labels ((helper (var1 var2) ; arg left out since it's not changed 
      (if (= arg var1) 
       var2 
       (helper (1+ var1) (1+ var2)))))     
    (helper 0 1))) 

这当然是一个的愚蠢的实施1+积极的论点。

+0

感谢您的回答,但是如果我想用浮点数和负数做同样的事情?我的目的是有一个带有2个参数的函数(第一个是列表,第二个是列表的一个元素),然后找到最接近的列表(第二个参数),计算他和所有元素之间的欧氏距离第一个参数。 – sici47

+0

参数是什么类型并不重要。只要你的函数使用与它实际类型一致的函数,它就会工作。既然你知道第一个是数字列表,第二个也许是一个数字列表,你都很好。通过在计算中使用至少一个浮点数来获得浮点数。没有它,你可能会得到一个理性的。例如。 '(/ 3 4); ==> 3/4' while'(/ 3.0 4); ==> 0.75'。经验丰富的口译员可以用['mapcar'](http://clhs.lisp.se/Body/f_mapc_.htm)和/或['reduce']解决您的问题(http://clhs.lisp.se/Body /f_reduce.htm) – Sylwester

0

没有设置,返回病例列表的名单有关系:

(注:循环宏使用设置在某个点:P)

(defun euclid (v1 v2) 
    (sqrt (loop for x in v1 for y in v2 sum 
    (expt (- x y) 2)))) 


(defun closest (target listoflists distancefn) 
    (loop for l in listoflists for d = (apply distancefn (list target l)) 
    minimizing d into min 
    collecting (list l d) into col 
    finally (return 
     (loop for (vec dis) in col when 
     (eql dis min) collect vec)))) 

(closest '(1 2 3) '((1 2 2) (1 2 2) (2 2 2)) #'euclid) 
> ((1 2 2) (1 2 2)) 
+0

感谢您的回答,我有一个关于函数的问题:如果我只想提取最接近的向量(而不是目标,因为显然euclid是0),我该如何改变条件?再次感谢! – sici47

+0

该函数返回最近的向量列表(不是目标),以防在相同的最近距离处有多个向量。如果只有一个最接近的矢量,它将返回一个元素的列表。 希望它清楚。 顺便说一句一个带套会更清楚: '(defun定义closest2(目标listoflists distancefn) (让(最接近(最小9999999)) (环路升的listoflists做 (让((d(适用distancefn(名单目标l))))) (if( Adax