2010-11-12 1 views
2

У меня проблемы с Lisp. То, что я пытаюсь сделать, - отслеживать количество раз, когда число появляется в x числе списков. Однако, запустив это снова и снова, lisp не воссоздает переменную, а использует конечное значение с последнего вызова функции. Поэтому мне интересно, как я могу преодолеть «обязательные» полномочия?Lisp Восстанавливает временную переменную

Итак, у меня есть какой-то список, как этот

(((8 7) (3)) ((8 3) (2)) ((7 3) (6)) ((7 2) (8)) ((6 7) (4 1)) 
((6 6) (4 1)) ((6 2) (2)) ((5 6) (3)) ((5 3) (8 3)) ((4 6) (4)) 
((4 4) (6)) ((4 1) (7)) ((3 7) (5 3)) ((3 4) (1)) ((3 3) (3)) ((3 1) (9)) 
((2 7) (7)) ((2 5) (2)) ((2 2) (5 2)) ((1 7) (1)) ((1 6) (6 1)) 
((1 1) (2 1)) ((1 0) (3)) ((0 7) (8 1)) ((0 5) (6)) ((0 3) (9 6)) 
((0 1) (1))) 

Тогда я звоню некоторые функции, как это, (объявление вара здесь, кажется, не делать ничего, мимо вызов исходной функции). .. Я предполагаю, что какой-то привязку от let.

(defun counter (possibleValues) 
(let ((var '(0 0 0 0 0 0 0 0 0 0))) 
    (loop for i from 0 to (list-length possibleValues) do 
     (loop for j in (cdr (nth i possibleValues)) do 
      (loop for k in j do 
       (incf (nth k var))))) 
    var)) 

Так что я могу запустить свой список с помощью функции и получить что-то вроде

(0 8 5 6 3 2 5 2 3 2) 

Каждой позиции со ссылкой на номер найденного в списке. Таким образом, значение 8 будет ссылаться на то, сколько раз 1 было найдено во всех списках (я рассматриваю только второй список). Теперь проблема .... запустить его дважды, и ...

(0 16 10 12 6 4 10 4 6 4) 

Я использовал ассоциативный список ранее, но в попытке понять это и не усложнять, я теперь с помощью списка. Я предполагаю, что другой вопрос у меня есть, как я могу создать ассоциативные элементы списка на лету? Мне не нравится объявлять «var», но я просто пытаюсь обойти «пусть» на данный момент. Мне не повезло с «setq» или «setf» ....

Заранее благодарим за вашу помощь!

+0

Вы повторяете I и получаете доступ к списку с помощью (NTH I ...) ??? Это выглядит ДЕЙСТВИТЕЛЬНО ПЛОХОЙ. –

ответ

4

Измените форму инициализации для VAR как выражение, которое создает новые списки, такие как (make-list 10 :initial-element 0) или даже (list 0 0 0 0 0 0 0 0 0 0).

В принципе, никогда не используйте цитируемые объекты, если у вас есть намерения по их модификации, поскольку последствия не определены, если вы это сделаете. Фактически, оценка этого определения функции дает предупреждение об этом:

 
; in: LAMBDA NIL 
;  (INCF (NTH K VAR)) 
; --> LET* 
; ==> 
; (SB-KERNEL:%SETNTH #:TMP5 #:TMP4 #:NEW3) 
; 
; caught WARNING: 
; Destructive function SB-KERNEL:%SETNTH called on constant data. 
; See also: 
;  The ANSI Standard, Special Operator QUOTE 
;  The ANSI Standard, Section 3.2.2.3 
; 
; compilation unit finished 
; caught 1 WARNING condition 
+0

Спасибо вам большое! Это сработало отлично! – jello

+0

@jello Это хорошая форма, чтобы принять это как правильный ответ :-) – invert