【问题标题】:Multiway tree construction from a node string从节点字符串构造多路树
【发布时间】:2010-07-28 09:50:48
【问题描述】:

有一个很棒的问题集叫做九十九Prolog Problems。问题 P70 是标题中提到的问题。这是一个很棒的 Prolog solution 这个问题只需要 5 行。但是,我对 Prolog 的理解是有限的。

这个解决方案在类似 C 的形式中看起来如何(没有可用的 itertools)?

根据要求编辑。我希望我没有侵犯版权。

问题:

BNF 中的语法:

tree ::= letter forest '^'
forest ::= | tree forest

使用差异列表的一个很好的解决方案:

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).

【问题讨论】:

  • 您可以通过在此处实际复制问题定义等来帮助我们。尽可能将内容引入 stackoverflow。

标签: algorithm prolog multiway-tree


【解决方案1】:

问题定义

(取自P-99: Ninety-Nine Prolog Problems

我们假设多路树的节点包含单个字符。在其节点的深度优先顺序序列中,只要在树遍历期间,移动是回溯到上一级,就会插入一个特殊字符^

按照这个规则,图中的树表示为:afg^^c^bd^e^^^


(来源:ti.bfh.ch

定义字符串的语法,并在给定String 时编写谓词tree(String,Tree) 来构造Tree。使用原子(而不是字符串)。使您的谓词双向工作。


解决方案第 1 部分: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)

使用虚拟root 节点可以简化事情。基本上算法如下:

  • 从左到右扫描字符串
  • 每当遇到节点标签时,我们都会创建一个新节点
    • 该节点被栈顶采用
    • 然后该节点被推入堆栈并成为新的顶部
  • 当我们遇到'^' 时,我们只是从栈顶弹出

解决方案第 2 部分: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('^')

如问题中所述,每当我们回溯到上一级时,我们都会插入^

【讨论】:

  • 这是一个非常好的解决方案。谢谢多基因润滑剂!错字:缺少“Tree2String”。如果孩子没有孩子,“访问”会发生什么?
  • @John:是的,FUNCTION string 应该是 FUNCTION Tree2String。当没有孩子时,FOREACH 将是一个无操作循环,这正是我们想要的。我将在下一次修订中添加此更正/澄清,以及我可能添加的其他内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多