我想把大数字分散到素数因素中。要做到这一点,我使用我的版本的Eratosthenes筛选(基本上我保持数组中范围内每个数字的最小素数因子)
protected final static int PowOf2= 21;
protected final static int[] Sieve = new int[(int) Math.pow(2,PowOf2)];
protected final static int range = (int) Math.pow(2,PowOf2); //range of long types
static int a=0; //counter
public static void init(long n){
for(int i=0; i<range-1; i++){
Sieve[i]=i; //at first every number is equal to it's index
}
for(int i = 2; i*i <= range-1; i++)
{
if (Sieve[i] == i){
for (int j = 2 * i ; j <= range-1; j += i)
{
Sieve[j] = i; //after that every number(index) has a smallest prime factor assigned to it
}
}
}
}
然后我使用这个数组将给定数字除以素因子
public static long[] intoPrimeFactors (long n){
long[] array = new long[range-1];
while(!isPrime(n)){
array[a]=Sieve[(int)n]; //here's an error
n/=Sieve[(int) n];
a++;
}
array[a]=n;
return array;
}
总的来说,我已经完成了所有因素
public static void main(String[] args){
long n=new Long(args[0]);
init(Math.abs(n));
long[] array = intoPrimeFactors(Math.abs(n)); //here's an error
System.out.print(n+" = ");
if(n<0){
n=Math.abs(n);
System.out.print("-1*");
}
for(int i=0;i<=a;i++){
if(i!=a)System.out.print(array[i]+"*");
else System.out.print(array[i]);
}
}
它在小数字(int)上运行得很好但是当我输入类似9223371331的东西时,我得到ArrayOutOfBound错误(在函数main和intoPrimeFactors中)并且我不确定为什么。你能帮帮我吗?
答案 0 :(得分:1)
这是您初始化Sieve
的方式:
protected final static int[] Sieve = new int[(int) Math.pow(2,PowOf2)];
其大小为:2097152
然后在intoPrimeFactors
,
此代码将根据您输入的数字执行:
while(!isPrime(n)){
array[a]=Sieve[(int)n]; //here's an error
n/=Sieve[(int) n];
a++;
}
如果有足够大的非素数输入,则会尝试超出Sieve
的容量进行访问,从而产生ArrayOutOfBound
。异常中的错误消息还会告诉您Sieve
的确切索引。
那你能做什么?首先,有些事你不能做,这就是:
Sieve[(int) n]
如果n
太大,则值会溢出,您将获得与您想要的索引不同的索引,索引错误。我猜你做了这个演员来修复编译器错误,但它没有意义。使用long
变量作为数组索引,只有在int
范围内,才能将int
转换为int
。在这种情况下,索引变量应该声明为long
,而不是long
。但这不是你的情况,因为你想支持非常大的数字。
但即使您可以使用TOKEN_QUERY
作为数组索引,您的计算机是否有足够的内存来包含如此大的数组?我不信。如果要使用如此大的筛子,则需要创建自定义数据类型:
或者您可以在不使用筛子的情况下计算主要因子。请参阅此其他答案,例如:https://stackoverflow.com/a/12252237/641955