在回答another question on StackOverflow(推广一下)时,出现了这个问题,它生成了由一组有限的元素组成的所有序列,没有重复出现。如何通过使用dif/2来防止生成的序列中出现重复?
正如鲍里斯在评论中正确指出的那样,这个问题有很多现有的解决方案。然而,我对不使用累加器的解决方案感兴趣(即,已经挑选出的元素的列表与新比较的元素进行比较),而是使用dif/2
语句代替。
为了说明,在我的后续程序中,我有4个元素,经过4次递归调用后,发现了几个div/2
声明,声明到目前为止选择的4个元素是成对不相似的。从这个可以推断出,继续递归并查找第五个元素是没有意义的,因为在给定div/2
语句时没有元素。有没有办法将这种“知识”编码到程序中,以便它不再循环?
:- use_module(library(apply)).
:- use_module(library(dif)).
sequences([]).
sequences([H|T]):-
maplist(dif(H), T),
between(1, 4, H),
sequences(T).
目前,循环行为:
?- sequences(X).
X = [] ;
X = [1] ;
...
X = [4, 3, 1, 2] ;
X = [4, 3, 2, 1] ;
<LOOP>
你想只有长度为2或更长的列表,还是你想要一个通用的解决方案? – 2014-12-06 20:47:59
@Boris我希望程序能够为任意长度的列表/任意数量的元素(在这种情况下是红衣主教)工作。 2的下界确实没有必要,可以推广。 – 2014-12-06 20:50:04
是不是这相同:对于一个大小为N的集合,找到大小为0(或1或2 ...)的所有组合,直到N?或者我错过了什么? – 2014-12-06 21:02:38