【问题标题】:Representing a series of numbers as an xml tree将一系列数字表示为 xml 树
【发布时间】:2013-03-06 06:45:37
【问题描述】:

我有一些数字说 110,111,114,115,120,121,112,122,130,131 现在我需要在 xml 树中列出它们

 - 110
 - 111  
    -114
    -115
      -120
      -121
      -122
 - -112
   -130
   -131

也就是说,如果一个数字 x[i+1] 是 x[i] +1,那么两者都被添加为同一棵树的子节点。别的 x[i+1] 被添加到子树到 x[i]

我知道它必须以递归方式完成,但我是如此愚蠢以至于我无法做到这一点?急需帮助。

【问题讨论】:

  • 但是根据您的模式,130 和 131 节点不应该是 112 的子节点吗??

标签: c# xml algorithm recursion


【解决方案1】:

也就是说,如果一个数字 x[i+1] 是 x[i] +1,那么两者都被添加为同一棵树的子节点。否则将 x[i+1] 添加到子树到 x[i]

根据此描述,您不会到达树的高层。所以你的树应该如下所示:

- 110
 - 111  
    -114
    -115
      -120
      -121
      -122
        -112
          -130
          -131

只需跟踪最后一个父节点,如果 x[i+1] x[i] +1,则将父节点重新分配给最后一个节点。然后将新节点添加到保存的父节点

【讨论】:

  • 错了,他需要 112 成为 111 的直接兄弟,因为这两个满足 x[i+1] = x[i]+1。
  • 不,我猜是因为 112 不会紧跟在数组中的 111 之后,也就是称为 x。
  • 这就是他需要递归解决方案的原因。不管数组中出现的顺序是什么;所以这意味着 currentNode 应该总是大于前一个节点,如果不是向后迭代并找出它大于的最后一个前一个节点。
  • 你怎么知道顺序无关紧要?我从描述中看不到它
  • 那么这不会是一个很大的挑战:D,除了问题中的树显示的内容
【解决方案2】:

你需要一些堆栈;

stack<int> nodeHierarchy;

然后算法很简单:检查元素是否高于前一个。如果是这样,那将是它的兄弟姐妹或孩子。

否则你需要通过堆栈返回并再次执行。

如果元素是兄弟元素,则需要再次通过堆栈返回。

让我们假设 root 为 0 并且所有其他元素都高于 0。

nodeHierarchy.push(0); //root
foreach(int element){
    while(nodeHierarchy.top() + 1 >= element)nodeHierarchy.pop();
    //put element as next nodeHierarchy.top() child
    nodeHierarchy.push(element);
}

我相信,这就是你的想法,但你描述错了。如果我错了,其他两个答案应该是正确的。

【讨论】:

    【解决方案3】:

    它实际上像你描述的那样工作,但这种描述比递归更线性:

    如果一个数字 x[i+1] 是 x[i] +1 则两者都被添加为同一棵树的子节点。否则将 x[i+1] 添加到子树到 x[i]

    所以这只是一个循环,将前一个节点初始化为 xml 文档的根元素。对于提供的数列

    110,111,114,115,120,121,112,122,130,131 
    

    然后它会生成以下 XML (PHP Example):

    <?xml version="1.0"?>
    <root>
      <node value="110"/>
      <node value="111">
        <node value="114"/>
        <node value="115">
          <node value="120"/>
          <node value="121">
            <node value="112">
              <node value="122">
                <node value="130"/>
                <node value="131"/>
              </node>
            </node>
          </node>
        </node>
      </node>
    </root>
    

    所以在编写代码之前,我认为您首先需要更准确地指定您实际想要遵循的逻辑。除非它不明显,否则您无法决定是否要使用递归、xpath 表达式等来解决它。

    【讨论】:

      【解决方案4】:

      更新(有序)结果 XML:

        <root>
           <node value="110" />
           <node value="111">
               <node value="114" />
               <node value="115">
                   <node value="120" />
                   <node value="121" />
               </node>
           </node>
           <node value="112">
               <node value="122">
                  <node value="130" />
                  <node value="131" />
               </node>
           </node>
         </root>
      

      我曾经考虑过这段代码中的顺序

      XmlDocument doc = new XmlDocument();
      int[] numArray = new int[] { 110, 111, 114, 115, 120, 121, 112, 122, 130, 131 };
      XmlElement head = doc.CreateElement("root");      
      doc.AppendChild(head);
      
      XmlElement cur = doc.CreateElement("node");
      cur.SetAttribute("value", numArray[0].ToString());
      head.AppendChild(cur);
      int pos = 0;
      BuildXml(numArray, ref pos, ref doc, head, cur);
      

      和递归函数

      public static void BuildXml(int[] numArray, ref int pos, ref XmlDocument doc, XmlElement parNode, XmlElement curNode)
      {
          if (pos < numArray.Length-1)
          {
              if (numArray[pos] + 1 == numArray[pos + 1])
              {
                  XmlElement current = doc.CreateElement("node");
                  current.SetAttribute("value", numArray[pos + 1].ToString());
                  parNode.AppendChild(current);
                  pos++;
                  BuildXml(numArray, ref pos, ref doc, parNode, current);
              }
              else if (numArray[pos] < numArray[pos + 1])
              {
                  XmlElement current = doc.CreateElement("node");
                  current.SetAttribute("value", numArray[pos + 1].ToString());
                  curNode.AppendChild(current);
                  pos++;
                  BuildXml(numArray, ref pos, ref doc, curNode, current);
              }
              else
              {
                  XmlElement elem = null;
                  foreach (XmlElement nodes in doc.FirstChild.ChildNodes) GetNode(nodes, numArray[pos + 1], ref elem);                
                  XmlElement current = doc.CreateElement("node");
                  current.SetAttribute("value", numArray[pos + 1].ToString());
                  ((XmlElement)elem.ParentNode).AppendChild(current);
                  pos++;
                  BuildXml(numArray, ref pos, ref doc, ((XmlElement)elem.ParentNode), current);
              }         
          }
      }
      
      public static void GetNode(XmlElement elem, int val, ref XmlElement found)
      {
          if (int.Parse(elem.GetAttribute("value")) < val)
              if (found == null || int.Parse(found.GetAttribute("value")) < val) found = elem;
          foreach (XmlElement childElem in elem.ChildNodes) GetNode(childElem, val, ref found);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-09-02
        • 2021-09-21
        • 1970-01-01
        • 2013-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-30
        相关资源
        最近更新 更多