我试图首次使用Prolog的追加和长度谓词来分割列表,我相信它需要一个递归的解决方案。我是Prolog的新手,希望能帮助解决这个问题! :)
这是预期的代码输出:
?- splits([1,2,3],S).
S = [1]/[2, 3] ;
S = [1, 2]/[3] ;
false.
它需要一个列表并将其拆分,但它是通过使用仿函数创建一个结构来实现的,这是令我困惑的...我知道我需要使用append for this,但是怎么做所以?
到目前为止,这是我的代码:
splits([H | T], S) :-
length(T, len), len > 0,
它将一直运行直到列表的尾部为空,然后停止,但我无法弄清楚如何添加附加功能或使其递归...有人可以给我一个提示吗? :)
答案 0 :(得分:2)
我会说你几乎处于一个有效的实现中,你的评论append/3
可用于拆分列表。这确实是实例化append/3
中的(-,-,+)
。
您的问题中似乎唯一增加的要求是排除任何一个拆分为空的情况。这可以通过使用\==/2
检查术语之间的不等性来实现。
这导致以下代码:
splits(List, X/Y):-
append(X, Y, List),
X \== [],
Y \== [].
PS:请注意,在代码段中使用len
是错误的,因为len
不是Prolog变量而是原子。将原子传递给length/2
的第二个参数会产生类型错误,并在len > 0
中产生算术错误(前提是len
未定义为函数)。 (两个观察都与SWI-Prolog有关。)
希望这有帮助!
答案 1 :(得分:0)
这是一种递归方法:
splits([A,B|T], [A]/[B|T]).
splits([A|T], [A|R]/S) :-
splits(T, R/S).
第一个子句提供了将具有至少2个元素([A,B|T]
)的列表拆分为[A]/[B|T]
的基本情况(它只拆分了第一个元素)。
第二个条款规定[A|R]/S
是[A|T]
的分割,如果R/S
是T
的分割。所以它会生成"其他解决方案递归到基本情况。如果第一个列表只有两个元素,那么基本情况就会成功,并且回溯到递归情况会在第一次尝试时失败(这就是你想要的 - 没有更多解决方案),因为递归情况只有在第一个列表有三个或更多元素(A
加上递归查询中T
强制执行的两个元素。)
| ?- splits([1], S).
no
| ?- splits([1,2], S).
S = [1]/[2] ? ;
no
| ?- splits([1,2,3], S).
S = [1]/[2,3] ? ;
S = [1,2]/[3] ? ;
no
...