给定重复次数的另一个列表的重复列表
list of repetitions of another list given the number of repetitions
我正在尝试构建谓词 itrepeats(all,part,num0,num)
"all" 是 "part" 列表的完整重复列表。 "num"是"part"在"all"中的重复次数,"num0" 增加 "num"
例如:
itrepeats(['a','b','c','a','b','c','a','b','c'],['a','b','c'],0,R)
输出应该是:
R=3
另一个例子:
itrepeats(['a','b','c','c','a','b','a','b','b'],['a','b','c'],0,R)
输出应该是:
no
另一个 "all" 为空的示例:
itrepeats([],['a','b','c'],0,R)
输出应该是:
R=0
我试过这个,但它不起作用,即使只是两个元素的列表:
itrepeats([],[_],0,0).
itrepeats([A,B|R],[A,B|R2],0,N):-
N is N-1,
itrepeats(R,[A,B|R2],0,N).
我很确定它应该是这样的,在没有实际迭代的前一个元素的情况下执行下一次迭代,直到 "all" 为空,但我不知道如何做好。请帮忙,谢谢。
这可能对您有所帮助。
一个常见的 Prolog 习惯用法是使用 辅助谓词 来携带额外的状态作为额外的参数。在这里,我们需要一个 累加器 来计算匹配的子列表,我们以 0 作为其初始值:
number_of_sublists( [H|T] , SL , N ) :- number_of_sublists( [H|T], SL, 0, N ).
找到匹配子列表的过程非常简单:
- 如果想要的子列表是当前列表的前缀,则计数加1。
- 去除列表的头部并在尾部向下递归。
- 当列表为空时,累加器的值为匹配子列表的最终计数。
查找一个列表是否是另一个列表的前缀非常容易。只匹配列表项,直到一个列表为空。 (请注意,空列表将作为 every 列表的前缀找到。)
is_prefix_of( [] , _ ). % once the prefix list is empty, we're done: the prefix list is the prefix of the other list.
is_prefix_of( [X|Xs] , [X|Ys] ) :- % Otherwise, if the two lists share a common head,
is_prefix_of(Xs, Ys). % - then recurse down on the tails.
把它们放在一起你得到:
number_of_sublists( [] , _ , N , N ) . % once the list is exhausted, we're done. The accumulator is the final tally.
number_of_sublists( [H|T] , SL , X , N ) :- % otherwise...
( is_prefix_of(SL, [H|T]) % - if the sublist is a prefix of the list
-> X1 is X+1 % - then increment the accumulator by 1
; X1 is X % - else don't increment
), %
number_of_sublists( T, SL, X1, N ). % remove the head of the list and recurse down on its tail.
有人可能会注意到,使用 findall/3
和 append/3
可以更轻松地完成此操作,例如:
number_of_sublists( L, SL, N ) :- findall( SL , prefix_of(SL,L), Sls), length(SLs,N).
prefix_of( SL, L ) :-
append( _ , Sfx , L ) ,
append( SL , _ , Sfx ).
我正在尝试构建谓词 itrepeats(all,part,num0,num)
"all" 是 "part" 列表的完整重复列表。 "num"是"part"在"all"中的重复次数,"num0" 增加 "num"
例如:
itrepeats(['a','b','c','a','b','c','a','b','c'],['a','b','c'],0,R)
输出应该是:
R=3
另一个例子:
itrepeats(['a','b','c','c','a','b','a','b','b'],['a','b','c'],0,R)
输出应该是:
no
另一个 "all" 为空的示例:
itrepeats([],['a','b','c'],0,R)
输出应该是:
R=0
我试过这个,但它不起作用,即使只是两个元素的列表:
itrepeats([],[_],0,0).
itrepeats([A,B|R],[A,B|R2],0,N):-
N is N-1,
itrepeats(R,[A,B|R2],0,N).
我很确定它应该是这样的,在没有实际迭代的前一个元素的情况下执行下一次迭代,直到 "all" 为空,但我不知道如何做好。请帮忙,谢谢。
这可能对您有所帮助。
一个常见的 Prolog 习惯用法是使用 辅助谓词 来携带额外的状态作为额外的参数。在这里,我们需要一个 累加器 来计算匹配的子列表,我们以 0 作为其初始值:
number_of_sublists( [H|T] , SL , N ) :- number_of_sublists( [H|T], SL, 0, N ).
找到匹配子列表的过程非常简单:
- 如果想要的子列表是当前列表的前缀,则计数加1。
- 去除列表的头部并在尾部向下递归。
- 当列表为空时,累加器的值为匹配子列表的最终计数。
查找一个列表是否是另一个列表的前缀非常容易。只匹配列表项,直到一个列表为空。 (请注意,空列表将作为 every 列表的前缀找到。)
is_prefix_of( [] , _ ). % once the prefix list is empty, we're done: the prefix list is the prefix of the other list.
is_prefix_of( [X|Xs] , [X|Ys] ) :- % Otherwise, if the two lists share a common head,
is_prefix_of(Xs, Ys). % - then recurse down on the tails.
把它们放在一起你得到:
number_of_sublists( [] , _ , N , N ) . % once the list is exhausted, we're done. The accumulator is the final tally.
number_of_sublists( [H|T] , SL , X , N ) :- % otherwise...
( is_prefix_of(SL, [H|T]) % - if the sublist is a prefix of the list
-> X1 is X+1 % - then increment the accumulator by 1
; X1 is X % - else don't increment
), %
number_of_sublists( T, SL, X1, N ). % remove the head of the list and recurse down on its tail.
有人可能会注意到,使用 findall/3
和 append/3
可以更轻松地完成此操作,例如:
number_of_sublists( L, SL, N ) :- findall( SL , prefix_of(SL,L), Sls), length(SLs,N).
prefix_of( SL, L ) :-
append( _ , Sfx , L ) ,
append( SL , _ , Sfx ).