将一系列数字表示为xml树

时间:2013-03-06 06:45:38

标签: c# xml algorithm recursion

我有一些数字说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]

我知道它必须以递归的方式完成,但我是如此愚蠢以至于我无法做到正确吗?迫切需要帮助。

4 个答案:

答案 0 :(得分:0)

它实际上与您描述的一样,但该描述比递归更具线性:

  

如果数字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表达式来解决它。

答案 1 :(得分:0)

  

即如果数字x [i + 1]是x [i] +1,则两者都被添加为相同树的子项。否则x [i + 1]被添加到子树到x [i]

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

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

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

答案 2 :(得分:0)

你需要一些堆栈;

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 :(得分:0)

更新(订购)结果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);
}