在java中排列数组中的大型元素列表
您好,我有1000个重复元素的列表,若我想在删除重复元素后获得它们的所有排列,那个么什么是最好的、数学上最有效的方法呢在java中排列数组中的大型元素列表,java,arrays,algorithm,random,permutation,Java,Arrays,Algorithm,Random,Permutation,您好,我有1000个重复元素的列表,若我想在删除重复元素后获得它们的所有排列,那个么什么是最好的、数学上最有效的方法呢 Random rand = new Random(); for (int i = 0 ; i < 1000 ; i ++) { list.add(i,rand.nextInt(500)); } Random rand=new Random(); 对于(int i=0;i15的值需要时间,并且在一个点之后抛出异常堆内存溢出 如果这样更好,类会自动清除重复项
Random rand = new Random();
for (int i = 0 ; i < 1000 ; i ++) {
list.add(i,rand.nextInt(500));
}
Random rand=new Random();
对于(int i=0;i<1000;i++){
增加(i,兰特·耐克斯汀(500));
}
在上面我们得到了一个1000个元素的数组,并且也会有重复的元素。打印排列以便消耗更少的内存空间和时间的更好方法是什么
我曾经使用过递归置换算法,但是n>15的值需要时间,并且在一个点之后抛出异常堆内存溢出
如果这样更好,类会自动清除重复项
Set=newhashset();
Random rand=新的Random();
对于(int i=0;i<5000;i++){
集合。添加(i,兰特。耐克斯汀(100));
}
首先,生成所有排列需要时间。它花费了如此多的时间,以至于排列你的5000个元素所花费的时间将超过我们宇宙的估计年龄
其次,存储所有排列是低效的。相反,您希望动态生成排列。请看下面的代码:.就地置换。这首先对数组进行排序,并查找数组中的所有置换。在每次迭代中,它也会更改数组
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import org.apache.commons.lang3.ArrayUtils;
public class Permutate {
public static void main(String[] args) {
Permutate permutator = new Permutate();
Set<Integer> data = new HashSet<Integer>();
Random r = new Random();
for (int i = 0 ; i < 5000 ; i ++) {
data.add(r.nextInt(100));
}
int[] array = ArrayUtils.toPrimitive(data.toArray(new Integer[data.size()]));
Arrays.sort(array);
do{
System.out.println(Arrays.toString(array));
} while(permutator.permutate(array) != -1);
}
public int permutate(int[] array) {
int i, j;
for (i = array.length - 2; i >= 0; i--) {
if (array[i] < array[i + 1])
break;
}
if (i < 0) {
return -1;
}
for (j = array.length - 1; j > i; j--) {
if (array[j] > array[i])
break;
}
swap(array, i++, j);
for (j = array.length - 1; j > i; i++, j--) {
swap(array, i, j);
}
return 0;
}
public void swap(int[] array, int x, int y) {
array[x] ^= array[y];
array[y] ^= array[x];
array[x] ^= array[y];
}
}
导入java.util.array;
导入java.util.HashSet;
导入java.util.Random;
导入java.util.Set;
导入org.apache.commons.lang3.ArrayUtils;
公共类置换{
公共静态void main(字符串[]args){
Permutate permutator=新的Permutate();
Set data=new HashSet();
随机r=新随机();
对于(int i=0;i<5000;i++){
数据。添加(r.nextInt(100));
}
int[]array=ArrayUtils.toPrimitive(data.toArray(新整数[data.size()]);
数组。排序(数组);
做{
System.out.println(array.toString(array));
}while(permutator.permutate(数组)!=-1);
}
公共int置换(int[]数组){
int i,j;
对于(i=array.length-2;i>=0;i--){
if(数组[i]<数组[i+1])
打破
}
if(i<0){
返回-1;
}
对于(j=array.length-1;j>i;j--){
if(数组[j]>数组[i])
打破
}
交换(数组,i++,j);
对于(j=array.length-1;j>i;i++,j--){
交换(数组,i,j);
}
返回0;
}
公共无效交换(int[]数组,int x,int y){
数组[x]^=数组[y];
数组[y]^=数组[x];
数组[x]^=数组[y];
}
}
将所有列表项添加到集合中
-这将删除重复项,请参阅。不知道为什么你在之前的研究中还没有发现这一点……如果你想列出所有的排列,没有任何算法比n更有效!我知道如何保管复制品<代码>新建ArrayList(新建LinkedHashSet(Arrays.asList(array))其中array是字符串列表我编辑了一些我写错的值,但我仍然认为没有算法比O(n!)更有效。当然没有,输出的大小是O(n*n!)
。我从未尝试过,但我认为不能合理地排列超过30个元素。这是我每次尝试为更大的n获取它们时遇到的一个问题,我得到了堆内存错误。好吧,好吧。谢谢应该使用提供的代码解决内存问题,因为它只需要O(N)
额外的内存,而不是O(N*N!)
。当然,除非你把结果存储在某个地方。