7

正常に動作する n-ary ツリー ADT を作成しました。ただし、そのシリアル化を呼び出しクラスの変数に格納する必要があります。例えば。

    DomTree<String> a = Data.createTreeInstance("very_large_file.xml");
    String x = a.toString();

私はまさに必要な方法で目的を果たすメソッドを書きましたが、非常に大きな入力では永遠にかかります(100MBのxmlファイルで20分)-メソッドの時間を計り、xmlファイルからツリーを構築するのは速いですが、呼び出す上記の toString() は非常に遅いです。

@Override
public String toString(){
    return printTree(this);
}

public String printTree(AbstractTree<E> tree){
    if (tree.isLeaf()){
        return tree.getNodeName();
    }else{
        String tStr = tree.getNodeName() + "(";

        int i = 0;
        Iterator<AbstractTree<E>> child = tree.getChildren().iterator();
        while (i < tree.getChildren().size() - 1){

            tStr += printTree(child.next()) + ", ";
            i++;
        }
        tStr += printTree(child.next()) + ")";

        return tStr;    
    }
}

ツリーのトラバース方法ではなく、文字列の構築方法に関係していると思いますか? これを行うより良い方法はありますか?

更新: Skaffman の例に従って、次のコードは非常に大きな入力に対して outOfMemoryError を返します。

@Override
public String toString(){
    StringBuilder buffer = new StringBuilder();
    printTree(this, buffer);
    return buffer.toString();

}

public String printTree(AbstractTree<E> tree, StringBuilder buffer){
    if (tree.isLeaf()){
        return tree.getNodeName();
    }else{
        buffer.append(tree.getNodeName());
        buffer.append("(");

        int i = 0;
        Iterator<AbstractTree<E>> child = tree.getChildren().iterator();
        while (i < tree.getChildren().size() - 1){

            buffer.append(printTree(child.next(), buffer));
            buffer.append(", ");
            i++;
        }
        buffer.append(printTree(child.next(), buffer)); 
        buffer.append(")");

        return buffer.toString();   
    }
}

更新: Skaffmans の例を使用して、完全に動作するようになりました

4

6 に答える 6

17

そのような文字列連結は、非常に遅いです。StringBuilder を使用します。

@Override
public String toString(){
        StringBuilder buffer = new StringBuilder();
        printTree(this, buffer);
        return buffer.toString();
}

public void printTree(AbstractTree<E> tree, StringBuilder buffer){
    if (tree.isLeaf()){
        buffer.append(tree.getNodeName());
    } else {
        buffer.append(tree.getNodeName());
        buffer.append("(");

        int i = 0;
        Iterator<AbstractTree<E>> child = tree.getChildren().iterator();
        while (i < tree.getChildren().size() - 1){
            printTree(child.next(), buffer);
            buffer.append(", ");
            i++;
        }
        printTree(child.next(), buffer); 
        buffer.append(")");
    }
}
于 2009-07-14T16:04:12.100 に答える
6

ループ内で文字列連結を使用しないでください。スケーリングしません。

StringBuilder を使用します。これは、文字列連結のように、常に新しいオブジェクトを作成するわけではありません。

void print() {
StringBuilder sb = new StringBuilder();
sb.append("hello");
sb.append(" World!");
System.out.println(sb.toString());

}

于 2009-07-14T16:04:16.343 に答える
3

StringBuilder を見て、単純な連結を使用しないでください。StringBuilder をプロセス全体に渡します (またはグローバルにします)。

于 2009-07-14T16:03:25.813 に答える
-1

メモリ使用量を削減する方法として、String.intern()を見たいと思うかもしれません。これは、文字列プールからインターンされた文字列を使用します。重複する文字列が多い場合は、より高速になる可能性があります。インターンされた文字列の詳細については、こちら

于 2009-07-14T16:14:46.180 に答える