コレクションがあります:[1、2、3、4、5、6、7、8、9]そこから、ランダムな数の一意の要素を生成する必要があります。たとえば、次回は5、3、7、9、4です。 8.私の関数はうまく機能しますが、乱数を生成し、重複がまだないかどうかをチェックする関数を再帰的に呼び出すために、StackOverflowErrorがスローされることがあります。どうすればこれを防ぐことができるのだろうか。
3 に答える
1つの解決策は、再帰ではなく反復(afor
またはループ)を使用することです。while
もう1つの解決策は、コレクションの変更可能なコピーを作成することから始め、その要素から要素を選択するたびに、その要素を削除して、再選択のリスクがないようにすることです。(ただし、コレクションの実際のコピーを作成していることを確認してください。たとえばnew ArrayList<Integer>(originalCollection)
、元の要素から要素を削除しないようにします。)
おそらく、再帰を使用せずにこれを行う必要があります。より適切に機能する可能性のあるアルゴリズムの大まかなスケッチ:
- 空のリストを作成する
- ソース配列を調べて、50%の確率で各要素をリストに追加します
- リストを配列に変換します
- 配列でArrays.shuffle()を使用して、要素をランダムに並べ替えます
それでうまくいくはずです。
完全なリストの各要素は、特定の要素のコレクションに存在するか存在しないかのいずれかです。これは、バイナリを使用するように指示しています。
0b000000000
[]にマップされます。つまり、すべての数値が存在しません。
0b111111111
[1、2、3、4、5、6、7、8、9]にマップされます。つまり、すべての番号が存在します。
2進数として扱われる、2つの間の任意の数値は、コレクション全体のサブセットにマップされます。
0b001010101
[3、5、7、9]にマップ
範囲内の各2進数は、一意のサブセットにマップされます。あなたの例は、順序付けが重要かもしれないことを暗示しています。その場合は、個別に対処する必要があります。この方法では、最大2 ^ 9=512の異なる組み合わせが得られます。