Joh*_*ohn 5 algorithm prolog multiway-tree
有一个很好的问题集叫做Ninety-Nine Prolog Problems.问题P70是标题中提到的问题.这是一个很好的Prolog 解决方案,这个问题只需要5行.但是,我对Prolog的理解是有限的.
该解决方案如何以类似C的形式显示(没有可用的itertools)?
按要求编辑.我希望我不侵犯版权.
问题:
BNF中的语法:
tree ::= letter forest '^'
forest ::= | tree forest
Run Code Online (Sandbox Code Playgroud)
使用差异列表的好方法:
tree(TS,T) :- atom(TS), !, atom_chars(TS,TL), tree_d(TL-[ ],T). % (+,?)
tree(TS,T) :- nonvar(T), tree_d(TL-[ ],T), atom_chars(TS,TL). % (?,+)
tree_d([X|F1]-T, t(X,F)) :- forest_d(F1-['^'|T],F).
forest_d(F-F,[ ]).
forest_d(F1-F3,[T|F]) :- tree_d(F1-F2,T), forest_d(F2-F3,F).
Run Code Online (Sandbox Code Playgroud)
我们假设多路树的节点包含单个字符。在其节点的深度优先顺序序列中,^在树遍历期间,每当移动是回溯到上一层时,就会插入一个特殊字符。
根据这个规则,图中的树表示为:afg^^c^bd^e^^^

(来源:ti.bfh.ch)
定义字符串的语法,并编写谓词tree(String,Tree)来构造 给Tree定String的 。使用原子(而不是字符串)。让你的谓词在两个方向上发挥作用。
String2Tree使用堆栈这很容易。这是伪代码:
FUNCTION String2Tree(String str) : Tree
LET st BE New-Stack<Node>
LET root BE New-Node
st.push(root)
FOREACH el IN str
IF el IS '^'
st.pop()
ELSE
LET child BE New-Node(el)
LET top BE st.top()
top.adopt(child)
st.push(child)
RETURN New-Tree(root)
Run Code Online (Sandbox Code Playgroud)
使用虚拟root节点可以简化问题。本质上,算法如下:
'^',我们只需从堆栈顶部弹出Tree2String相反的方向是一个简单的递归问题:
FUNCTION string(Tree t) : String
LET sb BE New-StringBuffer
visit(t.root, sb)
RETURN New-String(sb)
PROCEDURE visit(Node n, StringBuffer sb)
sb.append(n.label)
FOREACH child IN n.children()
visit(child, sb)
sb.append('^')
Run Code Online (Sandbox Code Playgroud)
正如问题中所指定的,^每当我们回溯到上一个级别时,我们都会插入。