Prolog - 如何返回每个元素只出现一次的列表?

Posted

技术标签:

【中文标题】Prolog - 如何返回每个元素只出现一次的列表?【英文标题】:Prolog - How can I return a list where each element appears only once? 【发布时间】:2021-08-31 22:12:45 【问题描述】:

我有一个谓词 set/2 应该将第二个参数实例化为一个列表,其元素只是第一个参数中每个术语的一次出现。到目前为止我所拥有的是:

set([],OutList).
set([X|InList],OutList) :- \+member(X,InList), append([X], OutList, OutListNew), set(InList,OutListNew).                      
set([X|InList],OutList) :- member(X,InList), set(InList,OutList).

然后调用 set/2:

set([1,1,2,3],X).

返回真。那是一半 - 我希望 X 被实例化为 [1,2,3] - 但我不确定在这种情况下如何使 X 为真。任何帮助和解释将不胜感激。

【问题讨论】:

【参考方案1】:

您的 Prolog 应该警告您在第一个子句中有一个 singleton,即

set([],OutList).

这意味着当执行到这样的子句时,它成功,但OutList仍然未绑定。

现在应该清楚您需要用空列表替换OutList

另一个错误位于第二个子句中。

append([X], OutList, OutListNew) 应该改为 append([X], OutListNew, OutList)。作为样式注释,可以用这个统一代替:[X|OutListNew]=OutList,然后移到头部。

【讨论】:

我放弃了; OutList 应该绑定什么? 查看最后一个版本,我已经替换(澄清)了我的提示,并解决了另一个更重要的错误。 说真的,谢谢。两个小时的倾倒痕迹只让我走到了这一步。现在我可以睡觉了!【参考方案2】:

sort/2 删除重复项(msort/2 保留重复项,如果这是您想要的。

还有:https://www.swi-prolog.org/pldoc/man?predicate=list_to_set/2

【讨论】:

谢谢!但是我应该编写自己的函数来执行此操作;我正在尝试学习序言。完成 Learn Prolog Now 中的练习。 请仅在答案本身包含所有相关详细信息后才链接到外部网站。链接应该只支持您的答案。

以上是关于Prolog - 如何返回每个元素只出现一次的列表?的主要内容,如果未能解决你的问题,请参考以下文章

第十个算法-只出现一次的数字

LeetCode 0137. 只出现一次的数字 II

一个列表,找出只出现一次的元素

Leetcode No.137 只出现一次的数字 II

leetcode137. 只出现一次的数字Ⅱ

第一个只出现一次的字符