2014-01-25 108 views
8

我有一個任意大小的大數組。這是一個方形陣列。我試圖掌握如何像對角線那樣遍歷它,就像/而不是\(我已經知道該怎麼做)。我有以下代碼迄今:對角遍歷一個數組

char[][] array = new char[500][500]; 
//array full of random letters 
String arrayLine = ""; 
for (int y = 0; y < array.length; y++) { 
    for (int x = 0; x < array.length; x++) { 
     for (???) { 
      arrayLine = arrayLine + array[???][???]; 
     } 
    } 
    System.out.println(arrayLine); 
} 

我有三個環路,因爲這是我做的另一條對角線:

for (int y = 0; y < array.length; y++) { 
    for (int x = 0; x < array.length; x++) { 
     for (int z = 0; z < array.length-y-x; z++) { 
      arrayLine = arrayLine + array[y+z][x+z]; 
     } 
    } 
    System.out.println(arrayLine); 
} 

在我的努力,我繼續下去的邊界之外,並得到一個ElementOutOfBounds異常。說陣列是如下(3×3,而不是500×500):

A B C 
D E F 
G H I 

欲打印出以下作爲字符串:

A 
BD 
CEG 
FH 
I 

先前SO問題也有類似的問題,整數數組,並且該解決方案基於數組元素的總和。但我正在與字符工作,所以我想不出一種方法來得到它。

+2

想一想當添加會發生什麼數組中的每個點都有'i'和'j'。你會注意到B,(0,1)和D,(1,0)都和爲1.考慮這個應用程序。注意:檢查邊界也很重要。 – Obicere

+0

我不確定我關注。 A = 0,0,B + D = 1,1,C + E + G = 3,3,然後是3,3,然後是2,2 ...... – gator

+2

通過'i和j'我提到座標。 C,E和G的值爲2. F和H的值爲3.我的值爲4. – Obicere

回答

11

想想細胞的座標:

. 0 1 2 
0 A B C 
1 D E F 
2 G H I 

對於任何對角線,所有的元素都具有一個共同點:一個元素的座標的總和是一個常數。這裏是常數:

0 = 0+0 (A) 
1 = 1+0 (B) = 0+1 (D) 
2 = 2+0 (C) = 1+1 (E) = 0+2 (G) 
3 = 2+1 (F) = 1+2 (H) 
4 = 2+2 (I) 

最小常量是最小的座標和0。最大常數是最大的座標和。由於每個座標分量可以達到array.length - 1,因此最大常數爲2 * (array.length - 1)

所以要做的事情是遍歷常量。對於每個常量,迭代其座標和常數相加的元素。這可能是最簡單的方法:

for (int k = 0; k <= 2 * (array.length - 1); ++k) { 
    for (int y = 0; y < array.length; ++y) { 
     int x = k - y; 
     if (x < 0 || x >= array.length) { 
      // Coordinates are out of bounds; skip. 
     } else { 
      System.out.print(array[y][x]); 
     } 
    } 
    System.out.println(); 
} 

然而,這最終會遍歷了很多外的邊界座標的,因爲它在所有可能的y座標總是迭代,即使只有一個對角線包含所有可能座標爲y。讓我們更改y循環,以便僅訪問當前k所需的y座標。

超出範圍座標的一個條件是x < 0。替換的定義x解決:

x < 0 
k - y < 0 
k < y 
y > k 

所以當y > kx將是負面的。因此,我們只想循環,而y <= k

出界座標的其他條件是x >= array.length。解決:

x >= array.length 
k - y >= array.length 
k - array.length >= y 
y <= k - array.length 

所以當y <= k - array.lengthx會太大。因此,我們想從0或k - array.length + 1開始y,以較大者爲準。

for (int k = 0; k <= 2 * (array.length - 1); ++k) { 
    int yMin = Math.max(0, k - array.length + 1); 
    int yMax = Math.min(array.length - 1, k); 
    for (int y = yMin; y <= yMax; ++y) { 
     int x = k - y; 
     System.out.print(array[y][x]); 
    } 
    System.out.println(); 
} 

注意:我只證明此代碼正確。我沒有測試過它。

+0

你會如何編輯你的方法使其走向相反的方向? \而不是一個/ – Singh

+0

在這種情況下,對角線的所有元素都有這個共同點:座標差('y-x')是一個常數。答案的其餘部分大致相同。 –

+0

哪一部分我不得不改變以改變他的方法? (他原來的問題) – Singh

0

更簡單的方法是檢查索引是否等於array.length = 1;對於diagonalRight和diagonalLeft只檢查i是否等於Ĵ

實施例:

digonalLeft求和矩陣的\,因爲(0,0)(1,1)(2,2),使對角。 diagonalRight求和矩陣的/,因爲(0 + 2)=(1 + 1)=(2 + 0)= 2且2是array.length - 1.

long diagonalLeft = 0; 
long diagonalRight = 0; 

for (int i = 0; i < array.lenth - 1; i++) { 
    for (int j = 0; j < array.length -1; j++) { 
     if (i == j) digonalLeft += array[i][j]; 
     if (i + j == array.length - 1) diagonalRight += array[i][j]; 
    }  
}