2016-04-27 2 views
0

を使用して:- ソート私はLispでこの機能を持っているカスタム関数

(defun AddtoQueue (queue method) 
    (cond 
    ((eq method 'DFS) (append (growPath (car queue) (findCh (caar queue))) (cdr queue))) 
    ((eq method 'BFS) (append (cdr queue) (growPath (car queue)(findCh (caar queue))))) 
    ((eq method 'A) (SORT (append (cdr queue) (growPath (car queue) (findCh (caar queue)))) #'> :key #'pathLength )) 
    (T "not implemented") 
) 
) 

私は(ここではpathLengthという名前の)カスタム関数を使用してリストをソートする必要があります。私はsortについてのlispのドキュメントを読んでいますが、私は事を理解できません。私の質問は、正確に私の比較機能に与えるものですか?

比較関数(この場合は>ある)

(defun pathLength(point) 

    ;;distance from origin point 
    (setq x (- (length queue) 1)) 

    ;;distance from end(manhattan distance) by subtracting the coords. 
    ;;calc lists is adding or subtracting lists. 
    (setq y (calcLists (cadr (assoc (car point) coords)) (cadr (assoc terminal coords)) 'sub)) 


    (setq y (+ (car y) (cadr y))) 
    ;;sum of distance from start and end. 
    (+ x y) 
) 

答えて

4

比較関数は、2つの引数(比較される2つの要素)を取得します。引数は比較の前にキー機能(pathLength)を通過します。 TRACEを使用して、どの関数が呼び出されているかを確認できます。例:

(trace >) 
;=> (>) 
(sort (list 4 5 1) #'>) 
; 0: (> 5 4) 
; 0: > returned T 
; 0: (> 1 4) 
; 0: > returned NIL 
;=> (5 4 1) 
(trace 1+) 
;=> (1+) 
(sort (list 4 5 1) #'> :key #'1+) 
; 0: (1+ 5) 
; 0: 1+ returned 6 
; 0: (1+ 4) 
; 0: 1+ returned 5 
; 0: (> 6 5) 
; 0: > returned T 
; 0: (1+ 1) 
; 0: 1+ returned 2 
; 0: (1+ 4) 
; 0: 1+ returned 5 
; 0: (> 2 5) 
; 0: > returned NIL 
;=> (5 4 1) 
(untrace > 1+) 
;=> T 

コードに関するコメントはありません。

  1. リスプでは、関数と変数の命名規則は、単語間にダッシュを含むすべての小文字を使用することです。したがってAddtoQueueの代わりにadd-to-queueとなります。名前(シンボル)は通常自動的に大文字に変換され(コメントなどで書かれます)、実際のコードを書くときには小文字を使用してください。
  2. 終了括弧は一行に置かないでください。改行とインデントを使用して、プログラムの構造を表示します。
  3. SETQの代わりにLETを使用してローカル変数を定義する必要があります。
  4. ADD-TO-QUEUECONDは、シンボルにMETHODEQの場合のみ比較されますので、CASEがタスクに適しています。
  5. PATH-LENGTHQUEUEという変数を使用していますが、これはADD-TO-QUEUEのローカル変数です。 FLETを使用して、同じスコープ内で関数を移動する必要があります。
  6. TERMINALCOORDSという変数を使用していますが、いずれの関数にも存在しないようです。それらがグローバル変数(DEFVAR or DEFPARAMETERを使用して定義する必要があります)の場合は、名前の周りにイヤーマフ(アスタリスク)を追加して、*TERMINAL*,*COORDS*を表示する必要があります。

は、私は完全なコードなしでこれをテストすることはできませんが、コードは次のようになります。

(defun add-to-queue (queue method) 
    (flet ((path-length (point) 
      (let* ((x (1- (length queue))) 
        ;; It's better to use FIRST and SECOND instead of CAR and 
        ;; CADR when dealing with lists. 
        (temp (calc-lists (second (assoc (car point) *coords*)) 
            (second (assoc *terminal* *coords*)) 
            'sub)) 
        (y (+ (first temp) (second temp)))) 
      (+ x y)))) 
    (case method 
     (DFS 
     ;; Consider using full words for function names. So 
     ;; FIND-CHARACTER, assuming that's what CH means. 
     (append (grow-path (car queue) 
          (find-ch (caar queue))) 
       (cdr queue))) 
     (BFS 
     (append (cdr queue) 
       (grow-path (car queue) 
          (find-ch (caar queue))))) 
     (A 
     (sort (append (cdr queue) 
        (grow-path (car queue) 
           (find-ch (caar queue)))) 
      #'> :key #'path-length)) 
     ;; You could use `ECASE` to automatically signal an error 
     ;; if METHOD doesn't match any of the cases. 
     (otherwise "not implemented")))) 
+0

完璧な答え、あなたのおかげで。あなたは私が待っていたより多くのことを指摘しました。たった1ヶ月間Lispを使用していました。 – Segmentation

関連する問題