【问题标题】:Java: How to randomly go through an array?Java:如何随机遍历一个数组?
【发布时间】:2011-11-16 15:54:21
【问题描述】:

我有一个大小为 x 的数组,我需要随机遍历该列表,但每个元素都要访问一次。最有效的方法是什么?

【问题讨论】:

  • but getting to each element once - 这是否意味着您只想获取每个元素一次?并且在改组后不再获得该元素?
  • @Rakesh,是的,我只想获取每个元素一次。

标签: java random


【解决方案1】:

你要找的是随机播放

试试这个-

// Create a list
List list = new ArrayList();

// Add elements to list

// Shuffle the elements in the list
Collections.shuffle(list);

// Create an array
String[] array = new String[]{"a", "b", "c"};

// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(array));

【讨论】:

    【解决方案2】:

    只需shuffle 数组,然后对其进行迭代。

    Collections.shuffle(Arrays.asList(yourArrayReference));
    

    【讨论】:

    • 集合未定义。什么是集合?
    • Java collections。具体看算法部分。
    【解决方案3】:

    您可以使用随机数生成器(大多数面向对象语言默认提供该生成器),并使用第二个数组来跟踪您已经检查过的内容。

    基本上:

    1. 生成随机数
    2. 在主数组中搜索随机数
    3. 如果随机数不在已检查的数组中...
    4. ...然后检查主数组中的元素[随机]
    5. 将随机数添加到已检查数组的末尾

    【讨论】:

      【解决方案4】:

      这是一种节省时间和空间的方法。

      import java.util.Enumeration;
      import java.util.Random;
      
      public class RandomPermuteIterator implements Enumeration<Long> {
          int c = 1013904223, a = 1664525;
          long seed, N, m, next;
          boolean hasNext = true;
      
          public RandomPermuteIterator(long N) throws Exception {
              if (N <= 0 || N > Math.pow(2, 62)) throw new Exception("Unsupported size: " + N);
              this.N = N;
              m = (long) Math.pow(2, Math.ceil(Math.log(N) / Math.log(2)));
              next = seed = new Random().nextInt((int) Math.min(N, Integer.MAX_VALUE));
          }
      
          public static void main(String[] args) throws Exception {
              RandomPermuteIterator r = new RandomPermuteIterator(100);
              while (r.hasMoreElements()) System.out.print(r.nextElement() + " ");
          }
      
          @Override
          public boolean hasMoreElements() {
              return hasNext;
          }
      
          @Override
          public Long nextElement() {
              next = (a * next + c) % m;
              while (next >= N) next = (a * next + c) % m;
              if (next == seed) hasNext = false;
              return  next;
          }
      }
      

      【讨论】:

      • 那是非常不可读且可怕的代码。 5分钟后,我仍然看不到它在做什么。但是,如果它真的遍历一个数组(就像 OP 所问的那样),那么该数组必须被很好地隐藏。这个问题在 4 年前就已经回答了。
      • 它伪随机地枚举数组的索引。例如,如果您运行上述代码,您将得到类似 50 52 3 6 45 40 26 49 92 11 80 2 4 19 86 61 65 44 27 62 5 32 82 9 84 35 38 77 72 7 ... 的数组指数 0..99.
      • 它是一个linear congruential generator,很像Java本身使用的那个。基于列表中元素数量的模数意味着最多有一半的可能值超出范围。
      猜你喜欢
      • 1970-01-01
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      相关资源
      最近更新 更多