我在我的AI课程中有这个项目在lisp中创建一些函数,我无法理解为什么我的一个函数不能正常工作。该函数应该以列表作为参数并返回一个列表,其中来自给定列表的参数显示多次一次被组合在一起,如下所示: (2,4,6,5,4,6,7,2,3,4,75,87) - > (2,2,4,4,4,6,6,5,7,3,7,77)。 我首先创建了两个函数,一个从给定列表中删除给定的参数(brisi(x,l)),另一个函数计算元素x在列表l中显示的次数(brojPonavljanja(x,l))
(defun brisi (x l)
(setq duz (length l))
(setq i 0)
(setq br 0)
(loop
(when (= i duz)
(return)
)
(when (= x (nth i l))
(incf br)
)
(incf i)
)
(setq duz1 (- duz br))
(setq l1 (make-list duz1))
(setq j 0)
(setq i 0)
(loop
(if (/= x (nth i l))
(progn
(setf (nth j l1) (nth i l))
(incf i)
(incf j)
)
(incf i)
)
(when (= i duz)
(return l1)
)
)
)
( defun brojPojava (x l)
(if ( null l)
0
( if (= (car l) x)
(+ 1 (brojPojava x (cdr l)))
(brojPojava x (cdr l))
)
)
)
(defun skupi(l)
(setq duz (length l))
(setq l1 (make-list duz))
(setq i 0)
(setq pos 0)
(loop
(when (= i (length l))
(return l1)
)
(setf elem (nth i l))
(setf br (brojPojava elem l))
(when (> br 1)
(setf l (brisi elem l))
(setq j 0)
(loop
(when (= br j)
(return)
)
(setf (nth pos l1) elem) ; <-- ######
(incf j)
(incf pos)
)
(setq i -1)
)
(incf i)
)
)
所以最后一个函数skupi(l)会产生问题。我确实注意到一个奇怪的事件,有一次我使用我的brisi函数删除列表中重复的元素并将其复制到新列表,但是我删除重复元素的列表(列表l)突然改变之后一行代码(我在该行上放了一个箭头和几个#)。我不知道为什么会这样。
答案 0 :(得分:2)
你的风格与功能不太相似。例如,你可以用以下方式编写它(不是最有效,但更简洁):
(defun group-list (lst)
(when lst
(nconc (make-list (count (car lst) lst) :initial-element (car lst))
(group-list (remove (car lst) lst)))))
虽然我是为了学习而提供解决方案,而不是为了复制粘贴。
答案 1 :(得分:0)
您可以通过列表中的两次传递以及一些查找表(以及一些辅助函数)的帮助来迭代地执行此操作:
(defun gen-elements (element count)
(loop repeat count
collect element))
(defun group-list (list)
(let ((done (make-hash-table))
(counts (make-hash-table)))
(loop for element in list
do (incf (gethash element counts 0)))
(loop for element in list
if (not (gethash element done))
append (progn
(setf (gethash element done) t)
(gen-elements element (gethash element counts))))))