【发布时间】:2014-10-08 12:45:06
【问题描述】:
我正在尝试在 java 上实现 Fisher-Yates 洗牌算法。它可以工作,但是当我的 ArrayList 的大小> 100000 时,它会变得非常慢。我将向您展示我的代码,您是否看到任何优化代码的方法?我对 ArrayList 中的 .get 和 .set 的复杂性进行了一些研究,这对我来说是 O(1)。
更新 1:我注意到我的实现是错误的。这是正确的 Fisher-Yates 算法。我还包括了我的next() 函数,所以你们可以看到它。我用 java.Random 进行了测试,看看我的 next() 函数是否是问题所在,但它给出了相同的结果。我认为问题在于我的数据结构的使用。
更新 2:我做了一个测试,ArrayList 是一个 RandomAccess 实例。所以问题不存在。
private long next(){ // MurmurHash3
seed ^= seed >> 33;
seed *= 0xff51afd7ed558ccdL;
seed ^= seed >> 33;
seed *= 0xc4ceb9fe1a85ec53L;
seed ^= seed >> 33;
return seed;
}
public int next(int range){
return (int) Math.abs((next() % range));
}
public ArrayList<Integer> shuffle(ArrayList<Integer> pList){
Integer temp;
int index;
int size = pList.size();
for (int i = size - 1; i > 0; i--){
index = next(i + 1);
temp = pList.get(index);
pList.set(index, pList.get(i));
pList.set(i, temp);
}
return pList;
}
【问题讨论】:
-
所以下次只需使用“编辑”;D 请向我们展示 next() 方法,因为它也可能是瓶颈。
-
显示 next() 方法的代码......这可能需要这么长时间。
-
水晶球 : 在
next中是否创建了Random实例? -
你为什么使用
List而不是int[]? -
每次循环迭代时,您都在计算 pList.size(),请改用 size 变量,除此之外,如果在其中实例化随机类,瓶颈可能在下一个函数中函数将其拉出迭代循环,并将实例作为引用变量传递给下一个
标签: java algorithm arraylist shuffle