Prolog 仅删除唯一元素 [英] Prolog removing unique elements only

查看:35
本文介绍了Prolog 仅删除唯一元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想返回一个删除所有唯一元素的列表,例如

I want to return a list that removes all unique elements for example

remUniqueVals([1,1,2,2,3,4,4,5,6,6,6],Q).   
Q = [1,1,2,2,4,4,6,6,6].  

我的问题是目前我有返回

My problem is that currently I have code that returns

remUniqueVals([1,1,2,2,3,4,4,5,6,6,6],Q).  
Q = [1, 2, 4, 6, 6].

因此只返回这些非唯一值的第一个实例.这是我的代码:

So that only the first instance of these non-unique values are returned. Here is my code:

remUniqueVals([], []).  
remUniqueVals([Q1|RestQ],[Q1|Xs]) :-        
   member(Q1,RestQ),  
   remUniqueVals(RestQ,Xs).  
remUniqueVals([Q1|RestQ],Xs) :-  
   remove(Q1,[Q1|RestQ], NewQ),  
   remUniqueVals(NewQ,Xs).  

我可以看到 member(Q1,RestQ) 在第二次检查 1,2,4 时失败,因为它们现在不再在列表中,因此将它们删除.我想帮助解决这个问题,我的想法是检查 member(Q1, PreviousQ),这是最终 Q 中已经存在的元素.不知道如何实施,但任何帮助将不胜感激.

I can see that member(Q1,RestQ) fails when it checks 1,2,4 the second time because they are now no longer in the list and so removes them. I'd like some helping solving this problem, my thoughts are to check member(Q1, PreviousQ), where this is the elements already in the final Q. Not sure how to go about implementing that though any help would be appreciated.

更新:

好的,谢谢你的建议,我最终选择了这个:

Ok so thanks for the suggestions I ended up going with this in the end:

remUniqueVals(_,[], []).  
remUniqueVals(_,[Q1|RestQ],[Q1|Xs]) :-        
   member(Q1,RestQ), 
   remUniqueVals(Q1,RestQ,Xs).  
remUniqueVals(PrevQ,[Q1|RestQ],[Q1|Xs]) :-        
   Q1 = PrevQ, 
   remUniqueVals(PrevQ,RestQ,Xs).  
remUniqueVals(PrevQ,[_|RestQ],Xs) :-  
   remUniqueVals(PrevQ,RestQ,Xs). 

remUniqueVals(0,[4,1,1,3,2,2,5,5],Q).
Q = [1, 1, 2, 2, 5, 5].

remUniqueVals(0, [A,B,C], [1,1]).
A = 1,
B = 1,
C = 1.

推荐答案

这与原始解决方案类似,但它收集辅助列表中的非唯一值并检查它以避免从原始列表中删除最后一个:

This is similar to the original solution but it collects the non-unique values in an auxiliary list and checks it to avoid removing the last one from the original:

remove_uniq_vals(L, R) :-
    remove_uniq_vals(L, [], R).

remove_uniq_vals([], _, []).
remove_uniq_vals([X|T], A, R) :-
    (   member(X, A)
    ->  R = [X|T1], A1 = A
    ;   member(X, T)
    ->  R = [X|T1], A1 = [X|A]
    ;   R = T1, A1 = A
    ),
    remove_uniq_vals(T, A1, T1).

测试...

| ?- remove_uniq_vals([1,2,3,1,2,3,1,2,3,4,3], Q).

Q = [1,2,3,1,2,3,1,2,3,3]

(1 ms) yes
| ?- remove_uniq_vals([1,1,2,2,3,4,4,5,6,6,6], Q).

Q = [1,1,2,2,4,4,6,6,6]

yes

因此,如果第一个参数是输入,则谓词效果很好,并且它保持列表中其余元素的原始顺序.

So the predicate works great if the first argument is an input, and it maintains the original order of the remaining elements in the list.

然而,这个谓词并不完全关系,因为它不会在第一个参数是已知数量元素的未实例化列表而第二个参数是不同元素的列表的情况下失败.固定数量的元素.所以这样的事情会起作用:

However, this predicate is not completely relational in that it will fail a case in which the first argument is an uninstantiated list of a known number of elements and the second argument is a list of a different fixed number of elements. So something like this will work:

| ?- remove_uniq_vals([A,B,C], L).

B = A
C = A
L = [A,A,A]

(1 ms) yes

但是类似下面的事情失败了:

But something like the following fails:

| ?- remove_uniq_vals([A,B,C], [1,1]).

no

这篇关于Prolog 仅删除唯一元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆