簡體   English   中英

如何在Java中將遞歸函數轉換為迭代函數?

[英]How can I convert a recursive function into iterative function in java?

我正在使用以下代碼來解析小型xml文件,並且它可以成功運行。 但是,當我解析巨大的數據文件時,出現了堆棧溢出錯誤。 因此,我決定將此方法轉換為迭代樣式。 最初,在編寫此方法時,我創建了邏輯並成功編寫了邏輯,盡管當轉換為迭代樣式時,我已經完全迷失了方向,並且沒有得到所需的輸出。 這是我的遞歸代碼:

private void xmlParsing(Node node,int indent) throws IOException {
    if (node.hasChildNodes()) {
        Node firstChild=node.getFirstChild();
        xmlParsing(firstChild,indent+1);
    } else {
        System.out.println(node.getNodeName()+":"+node.getNodeValue()+":"+indent);
    }
    Node nextNode=node.getNextSibling();
    if (nextNode!=null) {
        xmlParsing(nextNode,indent);
    }
}

有人可以幫我將其轉換為將在單個函數下執行此邏輯的迭代函數嗎? 我希望我已經提出了明確的要求。

我的完整代碼:

package sample;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class NewTestClass {

    private Document doc = null;

    public NewTestClass() {
        BufferedWriter br=null;
        try {
            doc = parserXML(new File("debug.xml"));

            br=new BufferedWriter(new FileWriter("xmldata.txt"));
            xmlParsing(doc, 0,br);
        } catch(Exception error) {
            error.printStackTrace();
        } finally {
            try {
                br.flush();
                br.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    private void xmlParsing(Node node,int indent,BufferedWriter br) throws IOException {
        if (node.hasChildNodes()) {
            Node firstChild=node.getFirstChild();
            xmlParsing(firstChild,indent+1,br);
        } else {

            br.write(node.getNodeName()+":"+node.getNodeValue()+":"+indent);
            br.newLine();
        }
        Node nextNode=node.getNextSibling();
        if (nextNode!=null) {
            xmlParsing(nextNode,indent,br);
        }
    }

    public Document parserXML(File file) throws SAXException, IOException, ParserConfigurationException
    {
        return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
    }

    public static void main(String[] args)
    {
        new NewTestClass();
    }
}

我最初的錯誤:

Exception in thread "main" java.lang.StackOverflowError
    at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.getNodeValueString(Unknown Source)
    at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.getNodeValueString(Unknown Source)
    at com.sun.org.apache.xerces.internal.dom.DeferredTextImpl.synchronizeData(Unknown Source)
    at com.sun.org.apache.xerces.internal.dom.CharacterDataImpl.getNodeValue(Unknown Source)

您的問題是,您不僅要為孩子,還要為兄弟姐妹遞歸。 子遞歸完全可以,但是在您的情況下,遞歸的深度與文檔中(扁平化的)節點(不僅是元素)的數量一樣深。

改為這樣做:

private void xmlParsing(Node node, int indent) throws IOException {

    // iterate for siblings
    while (node != null) {

        // recurse for children
        if (node.hasChildNodes()) {
            Node firstChild = node.getFirstChild();
            xmlParsing(firstChild, indent + 1);
        } else {
            // do the leaf node action
        }

        node = node.getNextSibling();
    }
}

我認為您的標簽嵌套程度很高。 您可以發布示例XML文件嗎?

如果我理解正確,則您正在嘗試將xml轉換為具有特定格式的文本文件。 如果這是必需的,我建議您使用XSL和XML進行翻譯。 這很容易,也很靈活。

您可以在http://speakingjava.blogspot.com/2011/07/how-to-use-xml-and-xsl-in-java.html中找到示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM