2010-10-09 82 views
-1

我想编写一个函数,将2D数组的大小调整为给定的参数。其通用调整大小阵列:Java调整数组大小

public static int[][] resize(int[][] source, int newWidth, int newHeight) { 

     int[][] newImage=new int[newWidth][newHeight]; 
     double scale=newWidth/source.length; 
     for (int j=0;j<newHeight;j++) 
      for (int i=0;i<newWidth;i++) 
       newImage[i][j]=source[(int)(i/scale)][(int)(j/scale)]; 
     return newImage; 

上面的代码没有问题,它适用于整数大小调整。然而,问题出现时,我使用resize函数调整数组的大小为0.5。

int[][] newImage=new int[source.length][source.length]; 
newImage=resize(source,source.length/2,source[0].length/2); 
     return newImage; 

然后一切都变得疯狂。我得到了类似2147483647的outofboundserrorexception。问题在于第一个函数中的double scale变量以及我在最后一行的第一个函数中使用的类型转换。任何想法修复?

注意:source.length是数组的宽度(列),source [0] .length是高度(行)。

+3

2147483647恰好是2^31-1(java中signed int的最大值)。巧合?我想不是。快乐的编码。 – 2010-10-09 23:22:52

+0

[Java Array Manipulation]的可能重复(http://stackoverflow.com/questions/3886818/java-array-manipulation) – 2010-10-09 23:33:04

+0

SO缺少的是一组通用答案,向学生程序员解释如何调试程序。 – 2010-10-10 02:25:22

回答

2

scale变量的类型为double。你可能遇到下列情况:

int newWidth = 5; 
int sourceLength = 10; 
double scale = newWidth/sourceLength; 
// what is `scale` now? 

令人吃惊的是,现在的规模是0.0。这是因为将int除以int总会再次产生int

为了得到你想要的结果,你必须写:

double scale = ((double) newWidth)/sourceLength; 

double scale = 1.0 * newWidth/sourceLength; 

然后分工发生了doubleint,结果将是一个double ,在这种情况下预计为0.5

+0

啊,是的,这是,谢谢! – Snowman 2010-10-09 23:42:56

1

说明:

  1. 表达1/2是一个整数除法。它产生0.
  2. 将0赋值为double将使其变为0.0
  3. 1/0.0是浮点除法并产生Double.POSITIVE_INFINITY。
  4. 将Double.POSITIVE_INFINITY转换为int将产生Integer.MAX_VALUE。

肮脏的修复:

该代码是不是很有效,因为它不断双打和整数之间转换。您可以通过执行与整数坚持:

newImage[i][j]=source[i * source.length/newWidth][j * source.length/newWidth]; 

该解决方案无论如何都溢出如果newWidth * source.length> Integer.MAX_VALUE的,但我怀疑你会不会与矩阵是大一些的工作。

+0

谢谢这有助于.. – Snowman 2010-10-10 00:18:47

0

奇怪的是,这个工程:

String[] sArray = new String[10]; 
sArray[0] = "Zero"; 
sArray[1] = null; 
sArray[2] = "Two"; 
sArray[3] = "Three"; 
sArray[4] = null; 
sArray[5] = "Five"; 
sArray[6] = "Six"; 
sArray[7] = null; 
sArray[8] = null; 
sArray[9] = null; 
assertTrue(sArray.length == 10); // part of JUnit - not needed for program 

for (int i = sArray.length - 1; i > -1; i--) { 
    if (sArray[i] == null) { 
    // has nothing to do with the array element # 
    sArray = ((String[]) ArrayUtils.removeElement(sArray, null)); 
    } 
} 

assertTrue(sArray.length == 5); // part of JUnit - not needed for program 

诀窍是在指定为null作为removeElement调用的第二个参数。根本不直观!我期望传递我想要移除的数组元素,但是这并没有改变数组的大小。如果要执行多个条件,请将它们放入if语句中,然后在调用removeElement之前将该数组元素清零。

例子:

// any of these conditions will cause the array element to be removed. 
    if ((sArray[i] == null) || (sArray[i].equals("")) || (sArray[i].equals("deleteMe"))) { 
    sArray[i] = null; 
    sArray = ((String[]) ArrayUtils.removeElement(sArray, null)); 
    } 

任何人有这种额外的见解,以及为什么它的工作原理是这样的,为什么我从来没有见过它,但我已经搜查了许多遍!!!!