Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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_Arrays_Algorithm_Random_Permutation - Fatal编程技术网

在java中排列数组中的大型元素列表

在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的值需要时间,并且在一个点之后抛出异常堆内存溢出 如果这样更好,类会自动清除重复项

您好,我有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;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!)
。当然,除非你把结果存储在某个地方。