2013-11-02 17 views
2

的列表中删除列表中的排列假设我有列表在序言中,如何从列表

L= [[1,2,3], [3,2,1],[2,1,2],[3,1,2], [1,2,2]]. 

,你可以看到,[1,2,3][3,2,1][3,1,2]互为排列的列表。 [2,1,2][1,2,2]也是彼此的置换。

我的目标是删除列表中所有元素的排列。 结果列表应该是:

L'=[[1,2,3],[2,1,2]]. 

我的想法到目前为止是利用成员(X,L),以在列表中找到一个元素,那么使用permutation(X,Xperm)获得的X置换,然后检查是否Xperm 是在L,如果是的话,删除它。

然而,结果不是我想要的。

任何人都可以帮助我吗?

回答

0

消除重复项的一种方法是使用标准的递归过程来移除重复项,而不是通过统一直接检查相等性,更改代码以尝试统一已排序的列表。

/* This is the regular duplicate elimination 
    that sorts the head element before checking for duplicates 
*/ 
remove_dups([],[]). 
remove_dups([H|T], TT) :- msort(H,SH), contains_dup(SH,T), remove_dups(T, TT). 
remove_dups([H|T], [H|TT]) :- msort(H,SH), \+ contains_dup(SH,T), remove_dups(T, TT). 

/* This duplicate checker routine sorts the lists before trying to unify them */ 
contains_dup(_, []) :- fail. 
contains_dup(SH, [H|_]) :- msort(H, SH). 
contains_dup(SH, [_|T]) :- contains_dup(SH, T). 

该代码使用SWI的msort/2谓词。

这是demo on ideone

+0

如果L = [[0,0,1],[0,1,1]],remove_dups给了我X = [[0,1,1]]。这是不对的。是否因为SWI-prolog的排序会删除重复项?例如在我的序言实现中,sort([0,0,1])= [0,1]。 – user2683732

+0

@ user2683732你说得对,我错过了那部分。 'sort/2'确实会删除重复项。切换到'msort/2'来避免这种行为。 – dasblinkenlight

0

上次我在Prolog上做了20多年前的事情,所以我不记得任何Prolog特定的东西。

但是,如果我以任何功能友好的语言来完成此操作,我会对大列表中的所有子列表进行排序,然后删除所有重复列表。

+0

我无法排序。他们可能是这样的子列表[3,2,2],排序会给[2,3],这不是我想要的。 – user2683732

+0

排序[3,2,2]应该给你[2,2,3] - 排序时不删除重复值,然后删除重复列表。 – zmbq

+0

奇怪,我使用SWI-prolog,sort([3,2,2],L)给了我L = [2,3]。 – user2683732