java置换生成算法中的奇怪错误

java置换生成算法中的奇怪错误,java,runtime-error,permutation,Java,Runtime Error,Permutation,我的算法生成数字0…n的置换,其中n可以是1到9之间的任意数字。它适用于从1到8的数字。但当我用9运行它时,它会运行一段时间。然后突然中止进程并退出。。。没有错误信息或任何类似的东西!我已经用java编写代码很长一段时间了,从来没有遇到过这个错误 我的算法:- package utils; import java.util.ArrayList; class Lexicography { static ArrayList<Long> perms = new ArrayLi

我的算法生成数字0…n的置换,其中n可以是1到9之间的任意数字。它适用于从1到8的数字。但当我用9运行它时,它会运行一段时间。然后突然中止进程并退出。。。没有错误信息或任何类似的东西!我已经用java编写代码很长一段时间了,从来没有遇到过这个错误

我的算法:-

package utils;

import java.util.ArrayList;

class Lexicography {

    static ArrayList<Long> perms = new ArrayList<Long>();

    public static void main(String[] args){
        long time = System.currentTimeMillis();
        getPermutations(Integer.valueOf(args[0]));

        System.out.println("\nSize:-"+perms.size()+"\nTime:-"+(System.currentTimeMillis()-time));
        //This println is never printed... java aborts before that
    }

    public static ArrayList<Long> getPermutations(int num){
        int[] n = new int[num+1];
        for(int i=0; i<=num; i++) n[i]=i;
        perms.add(getLong(n));
        for(int i=num; i>=0; i--) permutate(n[i],n);
        return perms;
    }

    private static void permutate(int k, int[] n){
        if(k>n.length) return;
        int p=0;
        for(int i:n){ if(i==k) break; p++;}

        for(int i=0; i<n.length; i++){
            if(i==p || n[i]<k) continue;
            n=swap(p,i,n);
            perms.add(getLong(n));
            System.out.println("i:"+(i+1)+" k:"+k+"    n:"+getLong(n));//this prints all permutations till the last one and then poof!

            for(int j=k-1; j>=0; j--) permutate(j,n);
            n=swap(p,i,n);
        }
    }

    private static int[] swap(int i, int f, int[] a){
        int t=a[f];
        a[f]=a[i]; a[i]=t;
        return a;
    }

    private static long getLong(int[] n){
        long ten=1, num=0;
        for(int i=n.length-1; i>=0; i--){
            num+=n[i]*ten; ten*=10;
        }
        return num;
    }

}
package-utils;
导入java.util.ArrayList;
课堂词典编纂{
静态ArrayList perms=新ArrayList();
公共静态void main(字符串[]args){
长时间=System.currentTimeMillis();
getPermutations(Integer.valueOf(args[0]);
System.out.println(“\n大小:-”+perms.size()+“\n时间:-”+(System.currentTimeMillis()-time));
//这个println从未被打印过…java在此之前中止
}
公共静态ArrayList getPermutations(int num){
int[]n=新的int[num+1];
对于(int i=0;i=0;i--)置换(n[i],n);
回烫;
}
私有静态void置换(int k,int[]n){
如果(k>n.length)返回;
int p=0;
对于(inti:n){if(i==k)break;p++;}
对于(int i=0;i=0;i--){
num+=n[i]*10;10*=10;
}
返回num;
}
}

如果没有print语句,在8之前的数字运行速度相当快(对于8,它在280ms以下运行)。但对于9,它只是在打印最后一个排列后突然停止。有人能帮忙吗?谢谢大家!

问题不在于你的代码,而在于
系统。out
,它无法显示你在合理时间内提供给它的数据量,因此它会发出嘶嘶声。当我尝试运行您的应用程序时,它在6分钟后仍在运行,因此我取消了它,注释掉了print语句,然后再次运行它,这需要2秒钟(根据我的编译器)才能输出:

Size:-3628800
Time:-962
因此,我更改了您的代码,将数据打印到一个文件中,然后再次运行它,执行耗时4秒,并创建了一个漂亮的83.1 MB的输出文本文件。以下是我使用的代码(不过我会将其更改为使用较少的静态内容):

导入java.io.BufferedWriter;
导入java.io.File;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.util.ArrayList;
课堂词典编纂
{
静态ArrayList perms=新ArrayList();
专用静态缓冲写入器输出;
公共静态void main(字符串[]args)引发IOException
{
File outputFile=新文件(“output.txt”);
如果(!outputFile.exists())
{
outputFile.createNewFile();
}
out=new BufferedWriter(new FileWriter(outputFile.getAbsolutePath());
长时间=System.currentTimeMillis();
getPermutations(整数.valueOf(“9”));
System.out.println(“\n大小:-”+perms.size()+“\n时间:-”+(System.currentTimeMillis()-time));
out.close();
}
公共静态ArrayList getPermutations(int num)引发IOException
{
int[]n=新的int[num+1];
对于(int i=0;i=0;i--)
{
置换物(n[i],n);
}
回烫;
}
私有静态void置换(int k,int[]n)引发IOException
{
如果(k>n.长度)
{
返回;
}
int p=0;
for(int i:n)
{
如果(i==k)
{
打破
}
p++;
}
for(int i=0;i=0;j--)
{
置换(j,n);
}
n=交换(p,i,n);
}
}
私有静态int[]交换(int i,int f,int[]a)
{
int t=a[f];
a[f]=a[i];
a[i]=t;
返回a;
}
私有静态long getLong(int[]n)
{
长十=1,num=0;
对于(int i=n.length-1;i>=0;i--)
{
num+=n[i]*10;
十*=10;
}
返回num;
}
}

我怀疑您的JVM资源有限,内存量已经接近极限。尝试在不打印的情况下运行,但使用
-verbosegc
创建
列表
将消耗分配的内存,只有当您有足够的可用内存时才可以

顺便说一句,我不会在正数前面打印一个
-
,因为它们看起来像负数。如果我在我的机器上运行,我会看到(没有
-

不打印

Size: 3628800
Time: 1420
使用
-mx128m

Size: 3628800
Time: 1894
使用
-mx100m
需要很长时间才能抛出

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.Long.valueOf(Long.java:577)
at Lexicography.permutate(Lexicography.java:31)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.getPermutations(Lexicography.java:19)
at Lexicography.main(Lexicography.java:9)

您需要至少128 MB的堆大小才能有效地运行此操作。

它对我有效。
大小:-3628800时间:-104847
看起来像是SIGSEGV:。我猜300多万个
长的
占用了太多内存?在我的笔记本电脑上,即使我不打印输出,问题仍然存在。另一种选择是使用
TLongArrayList
,它包装了
long[]
,但如果你可以花大约200美元购买32 GB,我只会使用更多内存。
Size: 3628800
Time: 1894
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.Long.valueOf(Long.java:577)
at Lexicography.permutate(Lexicography.java:31)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.permutate(Lexicography.java:34)
at Lexicography.getPermutations(Lexicography.java:19)
at Lexicography.main(Lexicography.java:9)