2016-08-27 3 views
0

私はバイナリツリーをシリアル化して逆シリアル化する次のコードを持っています。シリアル化は正常に動作しますが、逆シリアル化は正しくありません。私は配列インデックスカウンタ "i"をどのように非直列化に設定すべきかを理解するのに苦労しています。私がこれを理解するのを助けることができれば、本当に感謝しています。再帰カウンター

public class TreeNode { 
    int val; 
    TreeNode left; 
    TreeNode right; 

    TreeNode(int x) { 
     val = x; 
    } 
} 

public String serialize(TreeNode root) { 
    StringBuffer serial = new StringBuffer(); 
    helperSerialize(root, serial); 
    return serial.toString(); 
} 


public void helperSerialize(TreeNode node, StringBuffer serial) { 
    if (node == null) { 
     serial.append("null "); 
     return; 
    } 
    serial.append(new Integer(node.val).toString() + " "); 
    helperSerialize(node.left, serial); 
    helperSerialize(node.right, serial); 
} 

public TreeNode deSerialize(TreeNode root, String s) { 
    String[] split = s.split("\\s+"); 
    root = deSerialize(split, 0); 
    return root; 
} 

public TreeNode deSerialize(String[] s, int i) { 
    if(i >= s.length || s[i].equals("null")) 
     return null; 
    else { 
     int v = (int) s[i].charAt(0) - '0'; 
     TreeNode root = new TreeNode(v); 
     root.left = deSerialize(s, ++i); 
     i = i +1; // i should be incremented for next recursion 
     root.right = deSerialize(s, ++i); 
     return root; 
    } 
} 
+0

あなたの基本的なソースは、あなたがシリアライズよりも概念的に異なる方法でデシリアライズしようとしています。シリアル化するときに追加する整数トークン。デシリアライズのためにやっているこの奇妙なインデックスベースの代わりに、文字列バッファの最初のトークンを解析して消費してください。デシリアライズする前にint型のリストに解析することもあります。消費するときにリストの先頭をポップする方が簡単です。 –

+0

何が起きているのですか?値渡しで参照渡しではないので、ツリーにすべてのブランチで繰り返し値が返され、インデックスを含むパラメータにint []を渡してみてください。 – Wicpar

答えて

0

これを試してください(実装例としてインデックスを動作させるために)

public TreeNode deSerialize(TreeNode root, String s) { 
    String[] split = s.split("\\s+"); 
    root = deSerialize(split, new int[1]{0}); 
    return root; 
} 

public TreeNode deSerialize(String[] s, int[] i) { 
    if(i[0] >= s.length || s[i[0]].equals("null")) 
     return null; 
    else { 
     int v = (int) s[i[0]].charAt(0) - '0'; 
     TreeNode root = new TreeNode(v); 
     root.left = deSerialize(s, ++i[0]); 
     root.right = deSerialize(s, ++i[0]); 
     return root; 
    } 
} 

これは、このように枝をクローニングしない参照することによってインデックスを渡すことができます。

編集:次のように

あなたalgorythmは次のとおりです。

A 
/\ 
    B C 
/\/\ 
D E F G 

あなたがシリアライズ:あなたはデシリアライズ
ABDヌルヌルEヌルヌルCFヌルヌルGヌルヌル
を:
ABDをnull null null null null null
:配列ベースのイテレータ:
ABD null null null null null null null null null l null

ただし、 int v =(int)s [i] .charAt(0) - '0'; は間違っています.1つのchar番号しか許されないので、代わりにInteger.parse()を使用してください。

私はあなたの入出力を提供していないので、私はエラーであるとは見えませんが、参照と構文解析によるincermentationを行うと、うまくいくはずです。

+0

ありがとう!しかし、これは同様にインデックスを通り過ぎており、同じ誤った答えを持っています。 – Nish

+0

いいえ、今度は、インデックスを含む配列へのポインタを渡します。インクリメントを調整したいかもしれませんが、参照を使用するか、インクリメンタオブジェクトを使用する必要があります。 – Wicpar

0

完全な文字列をあらかじめ解析する代わりにScannerを使用することをお勧めします。それで、あなたはインデックスについて全く心配する必要はありません。

ここにいくつかのコードが動作しているようです。 (申し訳ありませんが、私はそれが簡単に実行されているサンプルをビルドするために作るためにいくつかのことを名前を変更して再配置。)混乱の

import java.util.Scanner; 

public class TreeNode { 
    int val; 
    TreeNode left; 
    TreeNode right; 

    TreeNode(int x) { 
     val = x; 
    } 

    TreeNode(int x, TreeNode left, TreeNode right) { 
     val = x; 
     this.left = left; 
     this.right = right; 
    } 

    public String serialize() { 
     StringBuffer serial = new StringBuffer(); 
     serializeHelper(this, serial); 
     return serial.toString(); 
    } 

    private static void serializeHelper(TreeNode node, StringBuffer serial) { 
     if (node == null) { 
      serial.append("null "); 
      return; 
     } 
     serial.append(new Integer(node.val).toString() + " "); 
     serializeHelper(node.left, serial); 
     serializeHelper(node.right, serial); 
    } 

    public static TreeNode deserialize(String serialized) { 
     Scanner scanner = new Scanner(serialized); 
     return deserializeHelper(scanner); 
    } 

    private static TreeNode deserializeHelper(Scanner scanner) { 
     String value = null; 

     if (scanner.hasNext()) { 
      value = scanner.next(); 
     } 
     if (value == null || value.equals("null")) { 
      return null; 
     } 

     return new TreeNode(Integer.parseInt(value), 
          deserializeHelper(scanner), 
          deserializeHelper(scanner)); 
    } 

    public static void main(String[] args) { 
     TreeNode root = new TreeNode(1, 
      new TreeNode(2, 
       new TreeNode(3), 
       new TreeNode(4)), 
      null); 

     String serialized = root.serialize(); 
     System.out.println(serialized); 

     TreeNode deserialized = deserialize(serialized); 
     // 1 2 3 null null 4 null null null 
     System.out.println(deserialized.left.right.val); 
     // 4 
     System.out.println(deserialized.serialize()); 
     // 1 2 3 null null 4 null null null 
    } 
}