2016-04-04 12 views
1

(更新)バイナリツリー/再帰(ジャワ)(更新)

私のクラスはハノイ、フィボナッチの塔のようなものを作成するために、再帰を使用することに取り組んできました

、およびすべてのその楽しいもの。問題は、私は本当にすべてをよく理解していないということです。私は再帰の一般的な概念を理解していますが、プログラムを作成するときにそれを実践することは私にとってとても複雑に感じます。私はそれが典型的な方法を何度も呼び出しているということを知っています。それは終了時の基本的なケースに到達しますが、私がしたいコードを書くのは難しいです。

私たちは現在、バイナリツリーに取り組んでいます。教授が提供するコードを使用してツリーを分割し、そのツリーに含まれるすべてのパスを出力する再帰的メソッドを作成する必要があります。

a 
b c 

B、Cがその下0人の子供を持っているでしょう:私たちの入力は、ツリーのだろう(a(b()())(c()()))ようなものになります。 (a)は可能なノードであり、()はそのパスの終わりとなる空のノードになります。私たちの目標は、私の例では、出力は次のようになりますので、すべてのパスをプリントアウトすることです:

a b 

a c 

我々が与えられたコードは、我々は再帰的なメソッドを記述するために使用できるヘルパーメソッドが含まれています

public class BinaryTree { 


public static void main(String[] args) { 
    Scanner scan = new Scanner(System.in); 
    String tree = scan.nextLine();//correct format : (a()()) 
    String[] t = splitTree(tree); 
    System.out.println(Arrays.toString(t)); 

} 
public static String[] splitTree(String tree) 
{ 
    //expected format 
    //(node tree tree) 
    //0 1 2-x x-(length-2) length-1 
    if(tree.length() <= 2)//tree not long enough to process 
     return new String[]{tree}; 

    String[] temp = new String[3]; 
    temp[0] = "" + tree.charAt(1);//grab tree node 
    tree = tree.substring(2, tree.length()-1);//remove node and outer paren 
    int parenCount = 0;//count of open paren 
    int endTreeOne = 0;//end of first tree 
    for(int i = 0; i < tree.length(); i++) 
    { 
     if(tree.charAt(i) == '(') 
      parenCount++; 
     if(tree.charAt(i) == ')') 
      parenCount--; 
     if(parenCount == 0) 
     { 
      endTreeOne = i; 
      break;//ends for loop early 
     } 
    } 
    temp[1] = tree.substring(0, endTreeOne+1);//left tree 
    temp[2] = tree.substring(endTreeOne+1);//right tree 
    return temp; 
} 

このメソッドは、基本的に(a(b()())(c()()))のような文字列を変換し、[a, (b()()), (c()())]にします。基本的にツリーを分割する。

私は再帰的メソッドを書くためにここからどのように進めるのか分かりません。私はかなり正直に失われた(と結果として)失望した。私は "()"が存在するかどうかをチェックする必要があると思っています。それがパスの終わりです。それが私が必要とするループから脱出する私の基本的なケースでしょうか?ツリーのどの辺を取るかを指定する方法がわかりません。誰かが何か助けやヒントを提供したり、これに取り組むための思考の正しい列車に乗ってくれたら、私はそれを高く評価します。私の再帰的な方法について

static ArrayList<String> path = new ArrayList<>(); 
public static String treePaths(String s) 
{ 

     String[] split = splitTree(s); 
     if(split[1].equals("()") && split[2].equals("()")) 
     { 
      path.add(split[0].toString()); 
      System.out.println(path.toString()); 
      return split[0]; 
     } 
     else 
     { 
      String s2 = ""; 
      for(int i = 0; i < split.length-1; i++) 
       { 
       s2 = split[i].toString(); 
       } 
       path.add(split[0].toString()); 
       return treePaths(s2); 

     } 

を、私はそれがすでに間違っているかなり確信している:

これまでのところ、私は本当にただ(上記のヘルパーメソッドに加えて)持っています。誰かが助けを与えることができれば(特に私の教授が提供するコードを使用すると)、私は非常に感謝しています。(私が正しい方向に向いているか、ここでは、私はそれが私はそれを行う必要があった方法が完了しているかどうかはわかりません

+0

私は、パスを保存するためにarraylistを使用することになっていると思います。うーん.. – ViviO

答えて

1

あなたは終了条件のヒントがヘルパーメソッドの冒頭に与えられています。 2文字以下であれば、入力を含む1サイズの配列を返します。空のノードがこのif文をトリガーします。

+0

申し訳ありませんが、私はあなたが言っていることに従うか分からない。私の再帰的メソッド(treePaths)の終了条件は入力の長さ程度でなければならず、入力が実際にはそれほど少ないのでしょうか?編集:hm、私はsplitTreeメソッドを与えられているので、[a、(b()()、(c()())](これらの3つの文字列の配列) – ViviO

1

大文字小文字が区別されないため、新しい答えを書いています 私は問題を解決しました(少なくとも、パスのみを印刷するオリジナルのもの)。

あなたは、再帰的メソッドの終了条件から始めなければならないということは間違いありません。
終了条件は何ですか?あなたが1つのパスの終わりに達すると、それはすべきです。終了して、メソッド呼び出しのスタックに上がります。
あなたが指定したソリューションの例を見ると、パスの終わりは、例の要素bとcのように、2つの空要素を子要素とする要素になります。
ヘルパーメソッドは

を続行あなたの4月5日あなたは「2つの空の要素を持っている要素を、」それを与える明確な出力が得られます。この場合には
終了条件がある

if (split[1].equals("()") && split[2].equals("()")) 

をおパスの終端を持ち、パスは再帰的なメソッドスタックによって保持されます。例えば
:パスのtreePaths()からa b c
最初のコールがaが発生しbを発生し、それがcが発生し、エンド・オブ・パスとして識別されるtreePaths() 3と呼ばれるtreePaths() 2と呼ばれます。
このシナリオを実行するためには何が必要ですか?これは、各メソッドに渡される入力をどのように形づくるのでしょうか?

+0

ヘルパーメソッドがnode()()を返すと、パスの最後にあることを意味するので、実際には終了するはずです。たとえばb()()と同様です。さもなければ、それは続けるべきです、そうですか?これはまだ私にとっては少し紛らわしいものです。 :( – ViviO

+0

はい、あなたは正しいことを得ました。あなたは 'split [i] =="() "'を書いている間に等号を使うべきだったので注意してください。 ? –

+0

あなたは答えがありますか?ステップでそれをやりたかったと思ったのですか?それとも既に解決しましたか? –