Algorithm 在Prolog中反转列表的一部分
我对这个Prolog函数的目标如下: 给定两个列表x和y,如果y可以通过反转列表x的连续部分由x构成,则返回true 例如,如果输入是x=[1,3,2,4],y=[1,2,3,4],那么结果应该是“true”,因为我们可以反转x的第二和第三个元素来得到yAlgorithm 在Prolog中反转列表的一部分,algorithm,prolog,Algorithm,Prolog,我对这个Prolog函数的目标如下: 给定两个列表x和y,如果y可以通过反转列表x的连续部分由x构成,则返回true 例如,如果输入是x=[1,3,2,4],y=[1,2,3,4],那么结果应该是“true”,因为我们可以反转x的第二和第三个元素来得到y 我真的不知道,我需要一些帮助 从算法上讲,您可以从索引0中比较两者,找出它们的不同之处(称此索引为“a”),并从n中向后比较,直到它们不同为止(称此索引为“b”) 然后在一个列表中从索引“a”反向到索引“b”,并比较列表(或子列表,无所谓),看
我真的不知道,我需要一些帮助 从算法上讲,您可以从索引0中比较两者,找出它们的不同之处(称此索引为“a”),并从n中向后比较,直到它们不同为止(称此索引为“b”) 然后在一个列表中从索引“a”反向到索引“b”,并比较列表(或子列表,无所谓),看看它们是否相同。如果是,则为真,否则为假 当两个列表相同时,将出现一种极端情况。这可以定义为true或false,具体取决于空集是否算作列表的连续部分
Search forward for mismatch:
[1,2,3,4]
[1,3,2,4]
^-------a
Search backward for mismatch:
[1,2,3,4]
[1,3,2,4]
^-----b
Reverse sub-list from a to b in either list:
[1,3,2,4] <-- Reversed sub-list indexed from 1-2
[1,3,2,4]
If equal, then true.
向前搜索不匹配项:
[1,2,3,4]
[1,3,2,4]
^-------a
向后搜索不匹配项:
[1,2,3,4]
[1,3,2,4]
^-----b
将任一列表中的子列表从a反转为b:
[1,3,2,4]这是一个开场白,你可以这样做:
rev(X,Y) :-
append(X1,X2,X3),
append(X3,X4,X),
reverse(X2,X5),
append(X1,X5,X6),
append(X6,X4,Y),
!.
示例:
?- rev([1,3,2,4],[1,2,3,4]).
true.
?- rev([1,4,3,2],[1,2,3,4]).
true.
下面是使用SICStus Prolog 4.3.1的直接实现:
:- use_module(library(lists)).
list_singlePartReversed(Xs,Ys) :-
same_length(Xs,Ys), % Xs and Ys are lists w/the same length
dif(Xs,Ys), % Xs and Ys are not equal
append(Prefix ,Xs0 ,Xs), % Xs and Ys have common prefix
append(Prefix ,Ys0 ,Ys),
append(Part ,Suffix,Xs0), % Xs and Ys have common suffix
append(Reversed,Suffix,Ys0),
reverse(Part,Reversed). % the rest of Xs is reversed in Ys
现在来看一些示例查询。。。首先,您在问题中发布的原始查询:
?- list_singlePartReversed([1,3,2,4], [1,2,3,4]).
yes
接下来是一个我们预计失败的简单案例:
?- list_singlePartReversed([1,4,3,2],[]).
no
那么所有可能的反转方法呢
?- list_singlePartReversed([1,2,3,4], Xs).
Xs = [2,1,3,4] ? ;
Xs = [3,2,1,4] ? ;
Xs = [4,3,2,1] ? ;
Xs = [1,3,2,4] ? ;
Xs = [1,4,3,2] ? ;
Xs = [1,2,4,3] ? ;
no
如果第一个参数没有实例化,但第二个参数是实例化的,该怎么办
?- list_singlePartReversed(Xs, [1,2,3,4]).
Xs = [2,1,3,4] ? ;
Xs = [3,2,1,4] ? ;
Xs = [4,3,2,1] ? ;
Xs = [1,3,2,4] ? ;
Xs = [1,4,3,2] ? ;
Xs = [1,2,4,3] ? ;
no
那么最一般的问题呢?我们得到无限解集的一个公平枚举吗
?- list_singlePartReversed(Xs,Ys).
Xs = [_A,_B], Ys = [_B,_A], prolog:dif([_A,_B],[_B,_A]) ? ;
Xs = [_A,_B,_C], Ys = [_B,_A,_C], prolog:dif([_A,_B,_C],[_B,_A,_C]) ? ;
Xs = [_A,_B,_C], Ys = [_C,_B,_A], prolog:dif([_A,_B,_C],[_C,_B,_A]) ? ;
Xs = [_A,_B,_C], Ys = [_A,_C,_B], prolog:dif([_A,_B,_C],[_A,_C,_B]) ? ;
Xs = [_A,_B,_C,_D], Ys = [_B,_A,_C,_D], prolog:dif([_A,_B,_C,_D],[_B,_A,_C,_D]) ? ...
出于好奇,您是否需要担心变量是无界的?比如,它应该返回规则([1,3,2,4],X)的所有正确答案。例如??-rev([1,4,3,2],])。
不会终止。列表如何[1,1]
?难道不可能逆转吗?