【问题标题】:Prolog flatten listProlog展平列表
【发布时间】:2011-09-17 01:04:37
【问题描述】:
flatten([A|B],R):- (islist(A)->(flatten(A,R1),R=R1);(write(A),append([A],R1,R))), flatten(B,R1).
    flatten(X,X).
    islist([_|_]).

这是我写的代码,但我有一个奇怪的问题..

我明白了

257 ?- flatten([1,[],2,[3],[3,[3,5]]],R).
1[]23335335
R = [1, [], 2, [3], [3, [3, 5]]] .

虽然写入的数字不是列表,但它们被附加为 list:S...

【问题讨论】:

  • 请改进代码的格式。事实上,它是不可能阅读的。
  • +1。不知道为什么有人给这个问题-1。有示例代码和输出表明不需要的行为。

标签: prolog


【解决方案1】:

你对 flatten/2 的定义有一些错误:

您的第一个子句将失败,因为如果 A 是一个列表,它将首先使用 R 实例化 R1,然后您尝试使用 flatten(B, R1) 再次统一它。

展平(X,X)。 -> 该子句保持列表“原样”,没有任何展平。

检查这个其他实现:

flatten(List, Flattened):-
  flatten(List, [], Flattened).

flatten([], Flattened, Flattened).
flatten([Item|Tail], L, Flattened):-
  flatten(Item, L1, Flattened),
  flatten(Tail, L, L1).
flatten(Item, Flattened, [Item|Flattened]):-
  \+ is_list(Item).

这里我们使用两个谓词:flatten/2 和 flatten/3。 “工作”将在 flatten/3 中完成,其中第二个参数将保存中间展平列表。

第一个子句是基本情况:当我们到达空列表时,我们就完成了,所以我们用中间扁平列表实例化第三个参数。

第二个子句处理递归。它展平列表中的第一项(无论是项还是子列表),然后继续处理输入列表的其余部分。

最后一个子句是非列表项的“基本情况”。它在中间展平列表的开头添加项目,但它只对不是列表的项目执行此操作,因为这种情况在第二个子句中得到了处理。

【讨论】:

  • 感谢您的解释。我有 1 天的 prolog 经验.. 有点奇怪 :)
猜你喜欢
  • 1970-01-01
  • 2013-11-08
  • 2021-12-24
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 2017-10-09
相关资源
最近更新 更多