Prolog 如何通过交错将列表列表构造成单个列表?

Posted

技术标签:

【中文标题】Prolog 如何通过交错将列表列表构造成单个列表?【英文标题】:Prolog How can I construct a list of list into a single list by interleaving? 【发布时间】:2018-02-27 02:37:08 【问题描述】:

如何将一个列表构建成一个带有交错子列表的列表? 像 recons([[1,2],[3,4]],X) 会给出 X= [1,3,2,4]? 我一直在尝试几个小时,我的代码总是给我非常奇怪的结果或无限循环, 我的想法是这样的:

recons([[A|R],REST],List):-
    recons(R,REST),
    append(A,[R|REST],List).

我知道这是完全错误的,但我不知道如何解决这个问题。

【问题讨论】:

它总是嵌套两层吗?或者这可以是任意深度吗? 另外一个我最近经常要给出的建议:尝试橡皮鸭调试:向你的橡皮鸭解释为什么你认为这种方法应该有效,试着说服你的橡皮鸭.通常你会开始看到问题,经过几次迭代,你就可以想出一个解决方案。 可能更深,例如 ([[1,4],[2,5],[3,6]],X) 可能会返回 [1,2,3,4,5 ,6] 【参考方案1】:

我们可以先考虑正确性,而不是先考虑效率。

interleaving_join( [[]|X], Y):- 
    interleaving_join( X,  Y).

这很清楚,但还有什么?

interleaving_join( [[H|T]|X],         [H|Y]):- 
               append(    X, [T], X2),
               interleaving_join( X2,    Y).

但是什么时候结束呢?当那里没有更多东西时:

interleaving_join( [], []).

确实,

2 ?- interleaving_join([[1,2],[3,4]], Y).
Y = [1, 3, 2, 4] ;
false.

4 ?- interleaving_join([[1,4],[2,5],[3,6,7]], X).
X = [1, 2, 3, 4, 5, 6, 7] ;
false.

这假设我们只想加入列表中的列表,无论元素是什么,例如[[...],[...]] --> [...]。特别是,我们不关心元素本身是否是列表。

有时将内部列表中的所有非列表元素(无论嵌套多深)收集到一个列表中(没有嵌套结构)可能会很有趣。事实上,这样的列表实际上是树,这被称为flattening,或收集树的边缘。这是一个不同的问题。

【讨论】:

以上是关于Prolog 如何通过交错将列表列表构造成单个列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过Prolog将字符串连接到列表中的多个元素?

如何在 Prolog 中附加列表?

如何将 csv 文件读入 SWI prolog 中的列表列表,其中内部列表代表 CSV 的每一行?

Prolog中的列表练习列表

如何在 Prolog 回溯期间获取值列表?

尝试使用prolog将变量分配/提取到列表列表中的不同元素