2015-06-03 21 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