2010-10-09 91 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)); 
    } 

任何人有這種額外的見解,以及爲什麼它的工作原理是這樣的,爲什麼我從來沒有見過它,但我已經搜查了許多遍!!!!