2015-11-26 2 views
0

У меня есть код, как показано ниже. Он вернется список, как (((1 . 2) (1 . 0)) ((1 . 2) (1 . 1)) ((1 . 2) (1 . 3)) ((1 . 2) (1 . 4)) ((1 . 2) (1 . 5)) ((1 . 2) (1 . 6)) ((1 . 2) (1 . 7)) ((1 . 2) (0 . 2)) ((1 . 2) (2 . 2)))LISP. Создать список пар

Интересно, если я могу переписать функцию generHod в пути, чтобы сделать его возвращать список как ((1.2 1.0) (3.4 4.2) (1.3 1.3)...)

(setf hod '()) 

(defun generHod (CurrX CurrY) 
    (dotimes (y 8) 
     (if (/= y CurrY) 
      (setf hod (append hod (list (append (list (cons CurrX CurrY))(list (cons CurrX y)))))) 
     ) 
    ) 

    (dotimes (x 8) 
     (if (/= x CurrX) 
      (setf hod (append hod (list (append (list (cons CurrX CurrY))(list (cons x CurrY)))))) 
     ) 
    ) 

) 
+0

Все эти добавления операции: плохой стиль. –

+0

Какое решение вы предлагаете? К сожалению, я не очень разбираюсь в разных функциях lisp, которые могут сделать это проще. –

+2

Я могу предложить вам бесплатную и бесплатную ознакомительную книгу Lisp, в которой объясняются основы: https://www.cs.cmu.edu/~dst/LispBook/index.html –

ответ

1

Во-первых:

(setf hod '()) 

Это плохой способ определить глобальная переменная; try

(defparameter hod()) 

Но зачем вообще использовать глобальную переменную? Функция может построить новый список и просто вернуть его. Если вызывающий абонент хочет вставить его в глобальную переменную, это зависит от вызывающего; он посторонний для работы функции.

(defun generHod ...) 

Синтаксис generHod не отличается от GENERHOD или generhod в Common Lisp под readtable по умолчанию. Все эти жетоны производят один и тот же символ. Лучше всего не играть в смешанные игры в идентификаторы Lisp; если вы хотите несколько слов, введите тире как gen-hod. Обычно generate сокращенно до gen англоговорящими хакерами, а не gener. См., Например, gensym funtion в Common Lisp.

В функции есть совершенно излишни append:

(append 
    (list (cons CurrX CurrY)) 
    (list (cons CurrX y)))) 

Узор (append (list X0) (list X1) ... (list XN)) можно переписать (list X0 X1 ... XN). Вы делаете лишние списки вещей только для добавления их вместе, чтобы составить один список, а не просто перечислять вещи в первую очередь.

Чтобы получить значения из целого числа с плавающей точкой, функция float может быть использован и loop макрос обеспечивает идиомы для переборе и собирая предметы:

(defun gen-hod (curr-x curr-y) 
    (let ((cxy (list (float curr-x) (float curr-y)))) ;; allocate just once! 
    (nconc ;; destructive append: use with care 
     (loop for y from 1 to 8 
      when (/= y curr-y) 
       append (list cxy (list (float curr-x) (float y)))) 
     (loop for x from 1 to 8 
      when (/= x curr-x) 
       append (list cxy (list (float x) (float curr-y))))))) 
Смежные вопросы