265

次の配列をランダムにシャッフルする必要があります。

int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1};

それを行う機能はありますか?

4

31 に答える 31

284

コレクションを使用してプリミティブ型の配列をシャッフルするのは少しやり過ぎです...

たとえばFisher–Yates shuffleを使用して、関数を自分で実装するのは簡単です。

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

class Test
{
  public static void main(String args[])
  {
    int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 };

    shuffleArray(solutionArray);
    for (int i = 0; i < solutionArray.length; i++)
    {
      System.out.print(solutionArray[i] + " ");
    }
    System.out.println();
  }

  // Implementing Fisher–Yates shuffle
  static void shuffleArray(int[] ar)
  {
    // If running on Java 6 or older, use `new Random()` on RHS here
    Random rnd = ThreadLocalRandom.current();
    for (int i = ar.length - 1; i > 0; i--)
    {
      int index = rnd.nextInt(i + 1);
      // Simple swap
      int a = ar[index];
      ar[index] = ar[i];
      ar[i] = a;
    }
  }
}
于 2009-10-05T13:53:47.470 に答える
181

ArrayList:を使用した簡単な方法は次のとおりです。

List<Integer> solution = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
    solution.add(i);
}
Collections.shuffle(solution);
于 2010-09-17T01:23:18.640 に答える
107

以下は、有効で効率的なフィッシャー・イェーツのシャッフル配列関数です。

private static void shuffleArray(int[] array)
{
    int index;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        if (index != i)
        {
            array[index] ^= array[i];
            array[i] ^= array[index];
            array[index] ^= array[i];
        }
    }
}

また

private static void shuffleArray(int[] array)
{
    int index, temp;
    Random random = new Random();
    for (int i = array.length - 1; i > 0; i--)
    {
        index = random.nextInt(i + 1);
        temp = array[index];
        array[index] = array[i];
        array[i] = temp;
    }
}
于 2013-08-27T04:34:19.217 に答える
14

Collections特にクラスを見てくださいshuffle(...)

于 2009-10-05T12:18:27.473 に答える
11

Collections.shuffleこのアプローチを使用した完全なソリューションは次のとおりです。

public static void shuffleArray(int[] array) {
  List<Integer> list = new ArrayList<>();
  for (int i : array) {
    list.add(i);
  }

  Collections.shuffle(list);

  for (int i = 0; i < list.size(); i++) {
    array[i] = list.get(i);
  }    
}

int[]Java がとInteger[](したがってint[]と)の間をスムーズに変換できないために問題があることに注意してくださいList<Integer>

于 2014-01-30T10:50:06.863 に答える
5

Java 8 を使用できるようになりました。

Collections.addAll(list, arr);
Collections.shuffle(list);
cardsList.toArray(arr);
于 2016-04-24T08:22:14.883 に答える
3

配列のジェネリック バージョンは次のとおりです。

import java.util.Random;

public class Shuffle<T> {

    private final Random rnd;

    public Shuffle() {
        rnd = new Random();
    }

    /**
     * Fisher–Yates shuffle.
     */
    public void shuffle(T[] ar) {
        for (int i = ar.length - 1; i > 0; i--) {
            int index = rnd.nextInt(i + 1);
            T a = ar[index];
            ar[index] = ar[i];
            ar[i] = a;
        }
    }
}

ArrayList は基本的に単なる配列であることを考慮すると、明示的な配列の代わりに ArrayList を操作し、Collections.shuffle() を使用することをお勧めします。ただし、パフォーマンス テストでは、上記と Collections.sort() の間に大きな違いは見られません。

Shuffe<Integer>.shuffle(...) performance: 576084 shuffles per second
Collections.shuffle(ArrayList<Integer>) performance: 629400 shuffles per second
MathArrays.shuffle(int[]) performance: 53062 shuffles per second

Apache Commons の実装である MathArrays.shuffle は int[] に制限されており、使用されている乱数ジェネレーターが原因でパフォーマンスが低下する可能性があります。

于 2014-11-04T08:05:36.953 に答える
3

リストをシャッフルする別の方法を次に示します。

public List<Integer> shuffleArray(List<Integer> a) {
    List<Integer> b = new ArrayList<Integer>();
    while (a.size() != 0) {
        int arrayIndex = (int) (Math.random() * (a.size()));
        b.add(a.get(arrayIndex));
        a.remove(a.get(arrayIndex));
    }
    return b;
}

元のリストから乱数を選択し、別のリストに保存します。次に、元のリストからその番号を削除します。すべての要素が新しいリストに移動されるまで、元のリストのサイズは 1 ずつ減少し続けます。

于 2018-03-09T11:10:35.000 に答える
1

誰もシャッフル コピー バージョンを書いていないので、私はこの非常によくある質問について検討しています。最近 Java テクノロジーを略奪していない人がいるArrays.javaでしょうか? ジェネリックと実装が含まれています。int

   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   @SuppressWarnings("unchecked")
   public static <T> T[] shuffledCopy(T[] original) {
      int originalLength = original.length; // For exception priority compatibility.
      Random random = new Random();
      T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), originalLength);

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }


   /**
    * Shuffles elements from {@code original} into a newly created array.
    *
    * @param original the original array
    * @return the new, shuffled array
    * @throws NullPointerException if {@code original == null}
    */
   public static int[] shuffledCopy(int[] original) {
      int originalLength = original.length;
      Random random = new Random();
      int[] result = new int[originalLength];

      for (int i = 0; i < originalLength; i++) {
         int j = random.nextInt(i+1);
         result[i] = result[j];
         result[j] = original[i];
      }

      return result;
   }
于 2016-05-31T21:11:22.167 に答える
1

別の方法もありますが、まだ投稿していません

//that way, send many object types diferentes
public anotherWayToReciveParameter(Object... objects)
{
    //ready with array
    final int length =objects.length;
    System.out.println(length);
    //for ready same list
    Arrays.asList(objects);
}

コンテキストに応じて、より簡単に

于 2016-10-27T17:42:56.580 に答える