我正在练习dcg技术,但我遇到了问题。我将实现转换BST树到列表(每个可能)和反向侧 - 列表ot bst(每个可能)。 (列表表示实际设置)
然而,
这个语法应该没问题,但它会产生非常多的重复。我知道原因(nil
),但我不能处理它。
bstToList(nil) --> [].
bstToList(t(Root, L, R)) --> [Root], bstToList(L), bstToList(R).
bstToList(t(Root, L, R)) --> [Root], bstToList(R), bstToList(L).
bstToList(t(Root, L, R)) --> bstToList(R), [Root], bstToList(L).
bstToList(t(Root, L, R)) --> bstToList(L), [Root], bstToList(R).
bstToList(t(Root, L, R)) --> bstToList(L), bstToList(R), [Root].
bstToList(t(Root, L, R)) --> bstToList(R), bstToList(L), [Root].
你能帮帮我吗?
答案 0 :(得分:2)
你如何实现它的问题是你在每个遍历步骤中混合每个遍历方法。换句话说,在每个遍历步骤中,您的谓词将探索每种遍历方法。
你需要在更高的层次上突破它们:
bst_to_list(BST, Ls) -->
bst_to_list_pre_LR(BST, Ls, _) |
bst_to_list_pre_RL(BST, Ls, _) |
bst_to_list_in_LR(BST, Ls, _) |
bst_to_list_in_RL(BST, Ls, _) |
bst_to_list_post_LR(BST, Ls, _) |
bst_to_list_post_RL(BST, Ls, _).
然后单独实现每种类型:
% Pre-order, left-to-right
bst_to_list_pre_LR(nil, Es, Es) --> [].
bst_to_list_pre_LR(t(Root, L, R), [_|Es0], Es) -->
[Root],
bst_to_list_pre_LR(L, Es0, Es1),
bst_to_list_pre_LR(R, Es1, Es).
% Pre-order right-to-left
bst_to_list_pre_RL(nil, Es, Es) --> [].
bst_to_list_pre_RL(t(Root, L, R), [_|Es0], Es) -->
[Root],
bst_to_list_pre_RL(R, Es0, Es1),
bst_to_list_pre_RL(L, Es1, Es).
... % Etc...
另外,请仔细阅读@ mat对您先前问题Prolog, reconstruct BST trees from inorder list的回答,因为这里提供了有用的技术,可以为每种情况提供更强大的解决方案。我在上面的代码中加入了这种技术。
请注意,您仍然可能会出现重复,因为某些树在以不同方式遍历时会产生相同的结果。
<小时/> 根据评论,似乎寻求一种解决方案来定义BST和节点列表之间的关系,使得BST中的顺序可以是任意的。由于订购可能是任何东西,它不适合DCG。这是一个可能的非DCG解决方案:
bst_list_all(BST, L) :-
tree_list_bound(BST, L, _),
bst_list_all_(BST, L).
bst_list_all_(nil, []).
bst_list_all_(t(Root, L, R), Es) :-
select(Root, Es, Es1),
append(Ls, Rs, Es1),
bst_list_all_(L, Ls),
bst_list_all_(R, Rs).
tree_list_bound(nil, [], []).
tree_list_bound(t(_, L, R), [_|Es0], Es2) :-
tree_list_bound(L, Es0, Es1),
tree_list_bound(R, Es1, Es2).
tree_list_bound(t(_, L, R), [_|Es0], Es2) :-
Es0 = [_|_],
tree_list_bound(R, Es0, Es1),
tree_list_bound(L, Es1, Es2).
谓词tree_list_bound
为解决方案建立了一个有界框架,以避免终止问题。它“感觉”这个解决方案可能会被浓缩,但我还没有找到办法。但是,它确实提供了解决所揭示问题的方法,而没有产生重复的解决方案。
?- bst_list_all(t(1,nil,t(2,t(3,nil,nil),nil)), L).
L = [1, 2, 3] ;
L = [1, 3, 2] ;
L = [2, 1, 3] ;
L = [3, 1, 2] ;
L = [2, 3, 1] ;
L = [3, 2, 1] ;
false.
?- bst_list_all(BST, [1,2,3]).
BST = t(1, t(2, t(3, nil, nil), nil), nil) ;
BST = t(1, t(3, t(2, nil, nil), nil), nil) ;
BST = t(2, t(1, t(3, nil, nil), nil), nil) ;
BST = t(2, t(3, t(1, nil, nil), nil), nil) ;
BST = t(3, t(1, t(2, nil, nil), nil), nil) ;
BST = t(3, t(2, t(1, nil, nil), nil), nil) ;
BST = t(1, t(2, nil, t(3, nil, nil)), nil) ;
BST = t(1, t(3, nil, t(2, nil, nil)), nil) ;
BST = t(2, t(1, nil, t(3, nil, nil)), nil) ;
BST = t(2, t(3, nil, t(1, nil, nil)), nil) ;
BST = t(3, t(1, nil, t(2, nil, nil)), nil) ;
BST = t(3, t(2, nil, t(1, nil, nil)), nil) ;
BST = t(1, nil, t(2, t(3, nil, nil), nil)) ;
BST = t(1, nil, t(3, t(2, nil, nil), nil)) ;
BST = t(2, nil, t(1, t(3, nil, nil), nil)) ;
BST = t(2, nil, t(3, t(1, nil, nil), nil)) ;
BST = t(3, nil, t(1, t(2, nil, nil), nil)) ;
BST = t(3, nil, t(2, t(1, nil, nil), nil)) ;
BST = t(1, nil, t(2, nil, t(3, nil, nil))) ;
BST = t(1, nil, t(3, nil, t(2, nil, nil))) ;
BST = t(2, nil, t(1, nil, t(3, nil, nil))) ;
BST = t(2, nil, t(3, nil, t(1, nil, nil))) ;
BST = t(3, nil, t(1, nil, t(2, nil, nil))) ;
BST = t(3, nil, t(2, nil, t(1, nil, nil))) ;
false.
?-