2012-04-03 5 views
1

実装にバグがあるか、StringBuilderが間違っているか分かりません。 stackoverflowから、私はJava Stringsが不変であることを知りました。現在私はStringBuilderを使用して再帰的な方法でいくつかの文字列処理を行っています。再帰をより明確かつ分かりやすくするために、Queueを使用してStringBuilderを保存しています。同じ処理がStringで実行できますが、実行時間が長くなるため、StringBuilderを使用しています。入力文字列は、最初にStringBuilderに変換され、その後、forループが文字と一致し、部分文字列をcharに置き換えた後にQueueに追加されます。この結果はStringBUilderQueueに加えられる。次に、要素(StringBuilder)がQueueから削除され、前と同じ方法でforループで処理されます。このプロセスは、Queueが空になるまで繰り返されます。以下は、私のコードは、これは私にStringIndexOutOfBoundsExceptionを与えるsnippet-再帰で使用しているときにStringBuilderが異常に動作しています

Queue<StringBuilder> q = new LinkedList<StringBuilder>(); 
    StringBuilder sb; 
    q.add(new StringBuilder("abcccc")); 
    while ((sb = q.poll()) != null) { 
     int len = sb.length(); 

     for (int i = 0; i < len - 1; i++) { 
      /* 
      * Here i am matching charAt(i) with charAt(i+1) and based on 
      * the characters matching decision is done 
      */ 

      StringBuilder rep = new StringBuilder(len - 1); 
      rep = sb; 
      rep.replace(i, i + 2, replace);//replace is a string which is a character 
      q.add(rep); 
      } 
    } 

です。しかし、元のStringBuilderの内容は変更されていません。これはsbです。私はちょうどのコピーを作成しています。それはrepです。そして、これを新しく作成した内容の置き換えます。StringBuilder

+1

あなたは 'ことを破棄している新しいのStringBuilder()':あなたはコピーをしたい場合

、初期値として文字列を受け取りStringBuilderのコンストラクタを使用します'rep'。 – Patrick

答えて

3

rep = sbは、sbのコピーを作成していません。これらのオブジェクトは、両方とも同じStringBuilderインスタンスを指しています。

+0

'StringIndexOutOfBoundsException'は' sb'のサイズが変更されたことを間接的に指し示します。ええ、あなたはマイクさんです。では今何ができるのですか? 'sb'のコピーを作るにはどうすればいいですか?私の代わりの方法は、repにsbの部分文字列を追加することです。そのトリックは 'string index = 0'では機能しません。 –

+0

コピーする方法の1つは、次のようにrepをインスタンス化することです: 'StringBuilder rep = new StringBuilder(sb.toString());' –

+0

これはクールですが、 'String'に関する限り、それらは不変で、私の再帰は入力に基づいて非常に大きくなります。したがって、この 'sb.toString()'は実行時間を増加させませんか? 代わりに、私がやっていることは、-StringBuilder rep = new StringBuilder(len-1); ' ' rep = sb; ' ' rep.append(sb.substring(0、i)); ' ' rep .append(replace); ' ' rep.append(sb.substring(i + 1)); ' ' q.add(rep); ' –

2

の参照をrepに割り当てているようですが、コピーを作成していないようです。すぐに再割り当てることによって

StringBuilder rep = new StringBuilder(sb.toString()); 

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html

+0

'String'は不変ですが、' sb'を文字列に変換しなければならない場合は、指定されたインデックス 'i'の文字を置き換える必要があります。結局、私は 'StringBuilder'文字列をキューに追加する必要があります。 –

+0

文字列は不変ですが、新しいStringBuilderは、このアプローチに従ってsbの文字列値のコピーで初期化された可変オブジェクトです。 –

+0

もう1つ質問があります。私は 'StringBuilder rep = new StringBuilder(sb)'を使って直接 'StringBuilder'のコピーを作成することができます。しかし、実際には、文字列の長さは毎回1文字ずつ減少していますが、新しいStringBuilder(sb.toString())を使用して 'StringBuilder'を作成すると、 'または' new StringBuilder(sb) 'です。不要な1つのメモリが必要になります。 (2文字が文字列の1文字に置き換えられるため) もっと良い方法を提案できますか?もし私が間違っていれば、私も修正してください。 –

関連する問題