我正在尝试通过添加到空列表来构建一个唯一的元素列表,使用LISP中的以下代码:
<application
android:name=".VolleyController"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ProductDetail"
android:parentActivityName=".MainActivity"
>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.curtrostudios.testapp.MainActivity" />
</activity>
<activity android:name=".Comments"
android:parentActivityName=".ProductDetail"
>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.curtrostudios.testapp.ProductDetail" />
</activity>
</application>
当我调用(makeset'(abbacdba))时,这个特殊的代码导致NIL - 它应该导致(abcd),而不考虑顺序) - 但它看起来像我应该从SET1添加一个原子每次迭代都没有在UNIQ中。你能不能添加到do循环中声明的空列表,还是我还有其他一些问题?顺便说一句,我正在使用clisp。
答案 0 :(得分:5)
<强> 1。使用正确的格式
在询问Common-Lisp时,请使用正确的格式。 例如,请参阅通过Google搜索"common lisp formatting conventions"返回的前三页。
以下是适用于您的功能的传统格式示例:
;;; Memset - return T if an atom is a top-level member of a set, else NIL
;;; This is needed for the makeset function
(defun memset (atm l)
(cond ((null l) nil)
((eql atm (car l)) t)
(t (memset atm (cdr l)))))
(defun makeset (set1)
(do ((uniq ()))
((null set1) uniq)
(cond ((not (memset (car set1) uniq))
(push (car set1) uniq)))
(setf set1 (cdr set1))))
<强> 2。尽可能使用原始函数
你的两个函数在Common-Lisp中都是原始的。
remove-duplicates
返回没有重复元素的列表,member
检查元素是否属于集合。
第3。功能中的错误
如果您仍想使用您的功能,而不是remove-duplicates
,则问题就在于此。
如果要修改列表,则应使用修改某些内容的函数。 cons
函数会构建一个新对,但 不会修改任何内容。因此,在您的表单(cons (car set1) uniq)
中,您可以向uniq
添加一个新元素,因为您获得了一个新列表,其中(car set1)
作为第一个元素,并且{ {1}}作为列表的其余部分,但是这个新列表会被立即丢弃,因为它没有分配给任何内容。
您可以使用宏setf
以这种方式将新值分配给局部变量unique
来更改此值:
uniq
或者您可以通过使用宏push
编写等效表单:
(setf uniq (cons (car set1) uniq))
最后,请注意(push (car set1) uniq)
函数中的cond
可以用更简洁的makeset
替换,从而产生此函数:
when
答案 1 :(得分:1)
所有更新都可以使用DO
中的步进表单完成。无需PUSH
或SETF
:
(defun makeset (set1)
(do ((uniq nil (if (memset (car set2) uniq)
uniq
(cons (car set2) uniq)))
(set2 set1 (cdr set2)))
((null set2) uniq)))