java置换生成算法中的奇怪错误
我的算法生成数字0…n的置换,其中n可以是1到9之间的任意数字。它适用于从1到8的数字。但当我用9运行它时,它会运行一段时间。然后突然中止进程并退出。。。没有错误信息或任何类似的东西!我已经用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
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)