Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:如何随机遍历数组?_Java_Random - Fatal编程技术网

Java:如何随机遍历数组?

Java:如何随机遍历数组?,java,random,Java,Random,我有一个大小为x的数组,我需要随机浏览列表,但每个元素只访问一次。做这件事最有效的方法是什么?你要找的是洗牌 试试这个- // 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",

我有一个大小为x的数组,我需要随机浏览列表,但每个元素只访问一次。做这件事最有效的方法是什么?

你要找的是洗牌

试试这个-

// 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));
只需对数组执行操作,然后对其进行迭代

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

您可以使用一个随机数生成器(在大多数面向对象语言中默认情况下是可用的),并使用第二个数组跟踪您已经检查的内容

基本上:

  • 生成一个随机数
  • 在主数组中搜索随机数
  • 如果随机数不在已检查数组中
  • …然后检查主数组中的元素[随机]
  • 将随机数添加到已检查数组的末尾

  • 这里有一个节省时间和空间的方法

    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;
        }
    }
    
    import java.util.Enumeration;
    导入java.util.Random;
    公共类RandomPermuteIterator实现枚举{
    INTC=1013904223,a=1664525;
    长种子,N,m,次之;
    布尔hasNext=true;
    公共随机PermuteIterator(长N)引发异常{
    if(N Math.pow(2,62))抛出新异常(“不支持的大小:+N”);
    这个,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));
    }
    公共静态void main(字符串[]args)引发异常{
    随机置换器r=新的随机置换器(100);
    while(r.hasMoreElements())System.out.print(r.nextElement()+);
    }
    @凌驾
    公共布尔值hasMoreElements(){
    返回hasNext;
    }
    @凌驾
    公共长期nextElement(){
    下一步=(a*下一步+c)%m;
    而(next>=N)next=(a*next+c)%m;
    如果(next==seed)hasNext=false;
    下一步返回;
    }
    }
    
    可能重复的
    ,但每个元素只能访问一次
    ——这是否意味着您只想访问每个元素一次?洗牌后再也不能得到那个元素了吗?@Rakesh,是的,我只想得到每个元素一次。这是非常不可读的,尽管很可怕的代码。5分钟后,我仍然看不到is在做什么。但是如果它真的遍历了一个数组(如OP-ask),那么这个数组必须隐藏得很好。这个问题在4年前已经得到了回答,它伪随机地枚举数组的索引。例如,如果您运行上面的代码,您将得到类似于50523645402692180241986616424276253282984353877727的结果。。。对于索引为0..99.0的数组,它与Java本身使用的数组非常相似。根据列表中元素的数量调整模的大小意味着最多有一半的可能值超出范围。集合未定义。什么是收藏?。具体看算法部分。