[解決済み】重複のない乱数の作成
2022-02-17 09:05:17
質問
この場合、MAXが5しかないので、1つずつ重複をチェックすればいいのですが、もっと簡単な方法はないでしょうか?例えば、MAXが20の場合はどうでしょうか? ありがとうございます。
int MAX = 5;
for (i = 1 , i <= MAX; i++)
{
drawNum[1] = (int)(Math.random()*MAX)+1;
while (drawNum[2] == drawNum[1])
{
drawNum[2] = (int)(Math.random()*MAX)+1;
}
while ((drawNum[3] == drawNum[1]) || (drawNum[3] == drawNum[2]) )
{
drawNum[3] = (int)(Math.random()*MAX)+1;
}
while ((drawNum[4] == drawNum[1]) || (drawNum[4] == drawNum[2]) || (drawNum[4] == drawNum[3]) )
{
drawNum[4] = (int)(Math.random()*MAX)+1;
}
while ((drawNum[5] == drawNum[1]) ||
(drawNum[5] == drawNum[2]) ||
(drawNum[5] == drawNum[3]) ||
(drawNum[5] == drawNum[4]) )
{
drawNum[5] = (int)(Math.random()*MAX)+1;
}
}
解決方法は?
最も単純な方法は、可能性のある数字のリスト(1〜20など)を作成し、それを
Collections.shuffle
. そして、必要な数の要素を取ればいいのです。これは、範囲が最終的に必要な要素の数と同じであれば、素晴らしいことです(例:カードのデッキをシャッフルする場合)。
例えば、1.10,000の範囲から10個のランダムな要素が欲しい場合、それはあまりうまくいきません - あなたは不必要に多くの作業を行うことになります。その場合は、これまでに生成した値のセットを保持しておき、次の値が存在しなくなるまでループで数値を生成し続ける方がよいでしょう。
if (max < numbersNeeded)
{
throw new IllegalArgumentException("Can't ask for more numbers than are available");
}
Random rng = new Random(); // Ideally just create one instance globally
// Note: use LinkedHashSet to maintain insertion order
Set<Integer> generated = new LinkedHashSet<Integer>();
while (generated.size() < numbersNeeded)
{
Integer next = rng.nextInt(max) + 1;
// As we're adding to a set, this will automatically do a containment check
generated.add(next);
}
しかし、セットの選択には注意が必要です。私は非常に意図的に
LinkedHashSet
これは、挿入順序を維持するためで、ここではそれが重要なのです。
さらに別の選択肢として 常に その都度、範囲を狭め、既存の値を補正することで、前進します。例えば、0〜9の範囲で3つの値が必要だとします。最初の反復処理では、範囲0〜9の任意の数値を生成し、仮に4を生成したとする。
2回目の反復処理では、0〜8の範囲の数字を生成します。生成された数値が4より小さければそのままにし、そうでなければ1を足す。この方法で7を得たとしよう。
3回目の繰り返しで、0〜7の範囲の数字を生成します。生成された数字が4より小さければ、そのままにする。4または5なら、1つ足す。6または7なら、2つ足す。こうすると、結果の範囲は4や6を除いた0〜9になる。
関連
-
[解決済み】「error: '.class' expected」の意味と修正方法について
-
[解決済み】Javaで無限大を実装する方法とは?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaScriptでランダムな文字列/文字を生成する
-
[解決済み] JavaScriptで特定の範囲のランダムな整数を生成する?
-
[解決済み] Javaで文字列値からenum値を取得する方法
-
[解決済み] 乱数(int)を生成する方法を教えてください。
-
[解決済み] JavaScriptで2つの数値の間の乱数を生成する
-
[解決済み] 英数字のランダムな文字列を生成する方法
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】HTTPステータス 405 - リクエストメソッド「POST」はサポートされていません (Spring MVC)
-
[解決済み】エラー:配列または java.lang.Iterable のインスタンスに対してのみ反復処理を行うことができます。
-
[解決済み】Eclipseがエラーメッセージ "Java was started but returned exit code = 1" を返す
-
[解決済み] メソッドがそのスーパークラスのメソッドをオーバーライドしない
-
[解決済み】なぜjava.io.Fileにはcloseメソッドがないのでしょうか?
-
[解決済み】Gradleがtools.jarを見つけ出さない
-
[解決済み] Hide Utility Class Constructor : ユーティリティクラスはパブリックまたはデフォルトコンストラクタを持つべきではありません。
-
[解決済み] JavaでSSLピアが正しくシャットダウンされない
-
[解決済み】Javaの未処理例外について
-
[解決済み] SQLエラー。0, SQLState: 08S01 通信リンクの失敗 [重複]。