Performance 在Prolog中的追加操作中使用差异列表的缺点是什么?

Performance 在Prolog中的追加操作中使用差异列表的缺点是什么?,performance,list,recursion,prolog,Performance,List,Recursion,Prolog,这是我们的后续问题 一般来说,append/3或conc/3的编写方式如下: append([], L, L). append([H1|T1], L2, [H1|L3]):- append(T1, L2, L3). 这种递归的缺点是,当将长列表作为第一个参数时,它不能有效地运行,因为在实际的追加开始之前需要处理整个列表 为了提高效率,我们可以使用不同的列表,这些列表只需要变量实例化,而不需要递归来追加列表 append_d(A1-Z1, Z1-Z2, A1-Z2). 问题是,无论我在

这是我们的后续问题

一般来说,append/3或conc/3的编写方式如下:

append([], L, L).
append([H1|T1], L2, [H1|L3]):-
    append(T1, L2, L3).
这种递归的缺点是,当将长列表作为第一个参数时,它不能有效地运行,因为在实际的追加开始之前需要处理整个列表

为了提高效率,我们可以使用不同的列表,这些列表只需要变量实例化,而不需要递归来追加列表

append_d(A1-Z1, Z1-Z2, A1-Z2).

问题是,无论我在哪里寻找
append/3
谓词的定义,都会使用前者,而不是更有效的替代方法。为什么呢?使用差异列表的缺点是什么?它们不是证明了效率提高的合理性吗?

我实际上将这个问题重新表述为:

与其他方法相比,使用
append/3
的缺点是什么

<>回答:频繁使用<代码>附件/3 通常表示数据结构>强>问题,在这种情况下,你应该退后一步,考虑<强>使用DCGs。< /P> 重复使用
append/3
通常意味着在使用DCG将其改进为线性时间(对所有操作进行合计)的情况下,二次开销这一事实已经证明了这一点

此外,使用DCG通常会使代码更易于阅读,因为您需要跟踪更少的参数和变量

既然您现在已经发布了几个关于列表差异的相关问题,我建议您暂时忘掉它们。在我看来,你在学习Prolog时使用的材料可能对CGS强调得太少了,因此你很快就会遇到更难的问题,即列表差异

当诱惑使用<代码>附件/ 3 时,请始终考虑使用DCGs<强>来描述列表!在我看来,它们被内部编译成谓词的事实,这一点现在不需要担心。稍后您将更容易理解列表差异

请注意,在使用DCG时,根本不需要
append/3
,因为由非终端描述的列表的串联更自然,例如:

?- phrase((a,b), Ls).
其中
a
b
都是非终端。注意如何将
(',')//2
理解为“and then”inDCGs,完全消除了
附加/3
的需要,也消除了很快理解列表差异的需要

编辑:我想引用出版物中的一段话来支持我的论点:

第二个错误是在课程中过早引入差异。 首先列出差异,然后才确定,这很有诱惑力 从句语法,但是初学者更熟悉语法规则


这绝对不是评论中要求的实证研究。尽管如此,我认为在一定程度上应该考虑到一位教授序言的老师在过去几十年里在至少3个不同国家的大学里为学生讲授序言的公开经验,即使我们忽略了这样一个事实,即我们身边有一个具体的初学者,他在过去2天里已经提出了3个不同的问题,关于列表差异。

我实际上会将这个问题重新表述为:

与其他方法相比,使用
append/3
的缺点是什么

<>回答:频繁使用<代码>附件/3 通常表示数据结构>强>问题,在这种情况下,你应该退后一步,考虑<强>使用DCGs。< /P> 重复使用
append/3
通常意味着在使用DCG将其改进为线性时间(对所有操作进行合计)的情况下,二次开销这一事实已经证明了这一点

此外,使用DCG通常会使代码更易于阅读,因为您需要跟踪更少的参数和变量

既然您现在已经发布了几个关于列表差异的相关问题,我建议您暂时忘掉它们。在我看来,你在学习Prolog时使用的材料可能对CGS强调得太少了,因此你很快就会遇到更难的问题,即列表差异

当诱惑使用<代码>附件/ 3 时,请始终考虑使用DCGs<强>来描述列表!在我看来,它们被内部编译成谓词的事实,这一点现在不需要担心。稍后您将更容易理解列表差异

请注意,在使用DCG时,根本不需要
append/3
,因为由非终端描述的列表的串联更自然,例如:

?- phrase((a,b), Ls).
其中
a
b
都是非终端。注意如何将
(',')//2
理解为“and then”inDCGs,完全消除了
附加/3
的需要,也消除了很快理解列表差异的需要

编辑:我想引用出版物中的一段话来支持我的论点:

第二个错误是在课程中过早引入差异。 首先列出差异,然后才确定,这很有诱惑力 从句语法,但是初学者更熟悉语法规则

这绝对不是评论中要求的实证研究。尽管如此,我认为,一位教授序言的老师在过去几十年里在至少3个不同国家的大学里为学生讲授序言的公开经验应该在一定程度上得到考虑,即使我们忽略了一个事实,那就是我们在大学里有一个具体的初学者
[a,b,c|Back]
?- append(A, B, [1,2,3]). % split a list
?- append([1,2,3], Back, List). % make a difference list
?- append(Prefix, _, [a,b,c,d]). % list prefix
?- append(_, Suffix, [a,b,c,d]). % list suffix
% tree_inorder_list(+Tree, -List, -Back)
tree_inorder_list(nil, List, List).
tree_inorder_list(t(X, L, R), List, Back) :-
    tree_inorder_list(L, List, [X|List0]),
    tree_inorder_list(R, List0, Back).
tree_inorder(nil) --> [].
tree_inorder(t(X, L, R)) -->
    tree_inorder(L),
    [X],
    tree_inorder(R).
?- tree_inorder_list(Tree, List, []).
?- phrase(tree_inorder(T), List).
?- listing(tree_inorder//1).
tree_inorder(nil, A, A).
tree_inorder(t(D, A, E), B, G) :-
    tree_inorder(A, B, C),
    C=[D|F],
    tree_inorder(E, F, G).

true.
?- list_to_search_tree([c,a,b], A),
   phrase(tree_inorder(A), List, Back),
   list_to_search_tree([z,y,z,z,x], B),
   phrase(tree_inorder(B), Back).
A = t(b, t(a, nil, nil), t(c, nil, nil)),
B = t(y, t(x, nil, nil), t(z, nil, nil)),
List = [a, b, c, x, y, z],
Back = [x, y, z].