为什么我不能将list.size设置为我的整型数组的长度?

问题描述:

我一直在挣扎几个小时,以消除我不明白的错误。 在下面的代码(int s = n [0])的第190行中,我得到一个数组超出范围的异常,因为我缩小了与数组e的关系。数组e在下面给出的代码顶部被声明为对象列表a(a.size())的长度/大小,如果我用任意整数替换大小(例如10),错误消失。为什么我不能将list.size设置为我的整型数组的长度?

为什么我不能将a.size设置为我的数组长度?有没有办法解决这个问题?

代码摘要:powerize(int n)应该将数字n写为具有最大指数的幂。因子分解将数字分解为素数的乘积,并且gcd返回整数数组的最大公约数。

public static Power powerize(int n) throws IllegalArgumentException { 

    List<Power> a = MathStuff.factorize(n); //make a list of Power objects from factorize n 
    int size = a.size(); 
    int[] e = new int[size]; 
    int[] b = new int[size]; 

    for (int i = 0; i < size; i++) { //collect all the base and exponent of each object in a. This LOOP 1 
     if(i >= a.size() || i >= e.length || i > b.length){System.out.print("Out of bounds in LOOP 1");} //test for out of bounds 
     e[i] = a.get(i).exponent; 
     b[i] = a.get(i).base; 
    } 

    int g = gcd(e); 


    int h = 1; //endproduct base 
    for (int i = 1; i < b.length; i++) { //Construct the base by taking the product of each base with its exponent divided by g. 
     if(i >= e.length || i >= b.length){System.out.print("Out of bounds in LOOP 3");} //test for out of bounds 
     h *= MathStuff.power(b[i], e[i]/g); 
    } 

    return new Power(h, g); //replace 2 

} 


/** 
* factorize n 
* 
* @param n the number to 'powerize' 
* @modifies none 
* @pre {@code 2 <= n} 
* @return factorization of n 
*/ 
public static List<Power> factorize(int n) { 
    List<Integer> f = new ArrayList<Integer>(); // f are factors 
    for (int i = 2; i <= n; i++) { 
     while (n % i == 0) { 
      f.add(i); 
      n /= i; 
     } 
    } 
    //return f; //returns factors 

    List<Power> p = new ArrayList<Power>(); // p are the factors with powers 
    for (int j = 2; j <= n; j++) { //j will be the base 
     int e = 0; //exponent 
     for (int k = 0; k <= f.size(); k++) { 
      if (f.get(k) == j) { 
       e++; 
      } 
     } 
     p.add(new Power(j, e)); 
    } 

    return p; //returns factors in powered form 
} 

/** 
* gcd returns the greatest common divisor of an integer array 
* @param n 
* @return greatest common divisor 
*/ 
public static int gcd(int... n) { 

    //------------------------------------------------THE ERROR OCCURS HERE 
    int s = n[0]; 

    for (int i = 1; i < n.length; i++) { 
     if (n[i] < s) { 
      s = n[i]; 
     } 
    } 

    while (s > 1) { 

     int counter = 0; 
     int modTot = 0; 

     while (counter < n.length) { 

      modTot += n[counter] % s; 
      counter++; 

     } 

     if (modTot == 0) { 
      return s; 
     } 

     s--; 

    } 
    //return 0 if there is no gcd 
    return 0; 
} 
+1

显然你用一个零长度数组调用'gcd';这意味着'e'是零长度,这意味着'MathStuff.factorize'返回一个零长度列表。 –

+0

显然,但我找不到原因。我声明了长度为a.size()的整数数组,尽管没有提供大小为0的对象列表a,但我的所有测试用例都失败了。 –

+1

因此,在调用'factorize'之后立即检查'a.size()> 0'。如果检查失败,这是'factorize'的问题。 –

这里:

public static int gcd(int... n) { 
int s = n[0]; 

此代码假定(不经任何进一步的检查),该gcd()用至少一个数组元素调用。但显然这不是事实。

请记住,你可以调用这样的方法:

gcd(); // NO array at all or 
gcd(someArray); // but someArray happens to be null ! 

所以,你必须退后一步,检查你的源代码所有情况下gcd()被调用。必须有一个你传递0参数的地方;或者你传递一个int的数组,实际上它是null。

我假设你的问题是为什么你不能使用size属性来设置数组的大小。

当一个数组被初始化时(通过new int[x]),操作系统将寻找一个连续的内存块,该内存块将足够大以容纳xints。一旦找到该内存,该阵列的大小将被固定为x

想想如果您可以使用size更改阵列大小会发生什么情况。这意味着,如果你想扩展这个数组,你将不得不接管它后面的内存。如果该内存被别的东西使用,该怎么办?这会造成问题。

但是,java.util.ArrayList可以在需要时为您解决此问题。所以如果你需要的话,这是解决方法。

+0

如果你指的是“导入”java.util.arraylist,我已经有了(我应该记住不要将它从代码中删除)。 如何解决这个问题? –

+0

这主要是因为它会扩展以适应您需要放置的许多元素。 –