zoukankan      html  css  js  c++  java
  • Shuffle an Array in Place

    Question: How do you shuffle an array in place?

    伪代码如下:

    To shuffle an array a of n elements (indices 0..n-1):
      for i from n − 1 downto 1 do
           j ← random integer with 0 ≤ ji
           exchange a[j] and a[i]

    // Shuffle a deck of cards
    Random random = new Random();
    for (int i = cards.size() - 1; i >= 0; i--) {
        int j = random.nextInt(i + 1);
        /* swap cards i,j */
        Card card = cards.get(i);
        cards.set(i, cards.get(j));
        cards.set(j, card);
    }

    The Fisher–Yates shuffle, as implemented by Durstenfeld, is an in-place shuffle. That is, given a preinitialized array, it shuffles the elements of the array in place, rather than producing a shuffled copy of the array. This can be an advantage if the array to be shuffled is large.

    To simultaneously initialize and shuffle an array, a bit more efficiency can be attained by doing an "inside-out" version of the shuffle. In this version, one successively places element number i into a random position among the first i positions in the array, after moving the element previously occupying that position to position i. In case the random position happens to be number i, this "move" (to the same place) involves an uninitialised value, but that does not matter, as the value is then immediately overwritten. No separate initialization is needed, and no exchange is performed. In the common case where source is defined by some simple function, such as the integers from 0 to n − 1, source can simply be replaced with the function sincesource is never altered during execution.

    To initialize an array a of n elements to a randomly shuffled copy of source, both 0-based:
      for i from 0 to n − 1 do
          j ← random integer with 0 ≤ ji
          if ji
              a[i] ← a[j

    a[j] ← source[i

    We'll start by writing out the numbers from 1 to 8 as before:

    Range Roll Scratch Result

        1 2 3 4 5 6 7 8  

    For our first roll, we roll a random number from 1 to 8: this time it's 6, so we swap the 6th and 8th numbers in the list:

    Range Roll Scratch Result

    1–8 6 1 2 3 4 5 8 7 6

    The next random number we roll from 1 to 7, and turns out to be 2. Thus, we swap the 2nd and 7th numbers and move on:

    Range Roll Scratch Result

    1–7 2 7 3 4 5 8 2 6

    The next random number we roll is from 1 to 6, and just happens to be 6, which means we leave the 6th number in the list (which, after the swap above, is now number 8) in place and just move to the next step. Again, we proceed the same way until the permutation is complete:

    Range Roll Scratch Result

    1–6 6 1 7 3 4 5 8 2 6
    1–5 1 5 7 3 4 1 8 2 6
    1–4 3 5 7 4 3 1 8 2 6
    1–3 3 5 7 4 3 1 8 2 6
    1–2 1 7 5 4 3 1 8 2 6

    At this point there's nothing more that can be done, so the resulting permutation is 7 5 4 3 1 8 2 6.

    reference:

    http://yuanhsh.iteye.com/blog/2181938

  • 相关阅读:
    Linux端口被占用解决
    Django Uwsgi Nginx 部署
    django 取出数据库的时间与当前时间相加减
    C++分支语句
    简单的C++程序
    菜鸟简短的自述以及C++介绍
    springboot maven项目打包SAPJCO3.JAR
    SAPJCO3升级3.1后报错java.lang.UnsatisfiedLinkError: sapjco3.dll解决
    sqlserver 修改数据库用户登录名
    yml字符串值写法,单双引号区别,换行用法
  • 原文地址:https://www.cnblogs.com/hygeia/p/5156450.html
Copyright © 2011-2022 走看看