2016-09-16 57 views
2

我有幾個以不同組合出現的二維數組,其中一個定義了中心,另外八個邏輯(而非物理上)放置在左側,右側,頂部,右上角等等。 'new array'的訪問方式如下: 如果x和y索引位於中心數組的邊界內,則訪問中心數組。如果索引超出邊界(或者是高於或者高於< 0),則訪問適當的相鄰數組(例如,對於x < 0和y < 0,左上角的數組被訪問)。Java在邏輯上連接數組

在此刻我正在手動解決數組索引的重新映射。下面是一個例子(沒有必要了解情況,我只是想表明所描述的過程中的結構):

public float noiseValueForCorner(int x, int y, int colorRight, int colorLeft, int colorTop, 
int colorBottom, int tileLeftUp, int tileRightUp, int tileLeftLower, int tileRightLower) 
{ 
// Out of bounds 
    if (x < -K2 || y < -K2 || x >= 4*K || y >= 4*K) 
     return -1.0f; 

if (y >= 0 && y < K2) 
{ 
    // corner itself 
    if (x >= 0 && x < K2) 
    return CornerNoise.noise[x][y]; 
    // left color 
    else if (x < 0 && colorLeft >= 0) 
    return ColorNoise[colorLeft].noise[K2-y-1][N2K+x]; 
    // right color 
    else if (x >= K2 && colorRight >= 0) 
    return ColorNoise[colorRight].noise[K2-y-1][x-K2]; 
} 
else if (y < 0) 
{ 
    // top color 
    if (x >= 0 && x < K2 && colorTop >= 0) 
    return ColorNoise[colorTop].noise[x][N2K+y]; 
     // top left tile 
    else if (x < 0 && tileLeftUp >= 0) 
    return TileNoise[tileLeftUp].noise[N2K+x][N2K+y]; 
    // top right tile 
    else if (x >= K2 && tileRightUp >= 0) 
    return TileNoise[tileRightUp].noise[x-K2][N2K+y]; 
} 
else //if (y >= K2) 
{ 
    // bottom color 
    if (x >= 0 && x < K2 && colorBottom >= 0) 
    return ColorNoise[colorBottom].noise[x][y-K2]; 
    // bottom left tile 
    else if (x < 0 && tileLeftLower >= 0) 
    return TileNoise[tileLeftLower].noise[N2K+x][y-K2]; 
    // bottom right tile 
    else if (x >= K2 && tileRightLower >= 0) 
    return TileNoise[tileRightLower].noise[x-K2][y-K2]; 
} 

return 2.0f; 
} 

的問題是,由於這種方法的許多人呼籲我的整個程序是相當慢。我想知道是否有更好的方法來做到這一點。我想到了一些有效的方法來將索引轉換爲單個數組的內存地址,以獲得一個新數組(因爲數組訪問完成得相當快)。

+0

陣列內,將其卸載到一個線程的幫助? –

+0

陣列或其放置位置更改的頻率以及您訪問「放置配置」的頻率? – Robert

+0

除了手動編碼所有情況下繁瑣的手動編碼之外,所顯示的代碼不一定很慢。使用分析器查找使用頻率和瓶頸。 FindBugs也可能會產生一些影響。 –

回答

0

您可以通過一些簡單(因此快速)的算術運算來映射座標。任何其他邊界檢查都不需要ifs。

首先簡單情況,9點的陣列,同一尺寸的正方形:

做一個[A X A]的數組的數組。您可以通過座標a來選擇數組,您可以通過獲取座標相對於a的模數來獲得數組中的索引。作爲一個例子:如果你有9個數組(這是一個3x3的數組數組),每個5x5,你的原始索引將從(-5,-5)到(5,5)運行。在這種情況下通過添加5來標準化可能是最簡單的,通常添加最低的索引值。因此,示例索引現在從(0,0)到(10,10)

查找數組除以5.結果是要使用的數組的索引,範圍(0,0)到(2,2)。您現在可以訪問適當的數組。將該結果稱爲x和y:nx,ny。

theArrays[nx, ny] 

數組中的索引只是通過使用%運算符和數組維數獲得的。

實施例:(8,-4)標準化爲(13,1)接入

(theArrays[2, 0])[3, 1]; 

擴展這對其中中央陣列是大和外陣列是小的時候,我們通過將歸一化進行管理的情況下中央陣列的尺寸。實際上,較低/左側的陣列被翻譯而留下空隙。

作爲一個例子,中央陣列是5 x 5,角落外部陣列是3 x 3,中央外部陣列是5 x 3或3 x 5.左下角陣列將從[-3,-3 ]到[0,0]標準化會移動左下角的數組以從[2,2]開始。

在外部數組大於中央數組的情況下,算術會稍微複雜一些,但仍可以在沒有if語句的情況下完成。

作爲示例,中心陣列爲3 x 3,外部陣列爲5 x 5,3 x 5和5 x 3。僅考慮一個維:

array 0   1  2 
-5 -4 -3 -2 -1 | 0 1 2 | 3 4 5 6 7 

所以輸入範圍從-5 ... 7.

我們要映射到陣列0,1或2

-5至-1 => 0,0到2 => 1,3到7 => 2

一種方法是使用查找表。這可能是最快的。爲了記錄這裏有一些算術來做到這一點。數組的大小E和C(邊緣和中心),請求的索引我

index of array = (2 * ((i + e)/(e + c))) + (((i + e) % (e + c))/e) 

sample values: 
     -5 => 0 + 0 => 0 
     -3 => 0 + 0 => 0 
     -1 => 0 + 0 => 0 
     0 => 0 + 1 => 1 
     2 => 0 + 1 => 1 
     3 => 2 + 0 => 2 

對於指數如果這個特殊的部分是緩慢的那就更簡單了

index within array = ((i + e) % (e + c)) % e 

     -5 => 0 % 5 => 0 
     -3 => 2 % 5 => 2 
     -1 => 4 % 5 => 4 
     0 => 5 % 5 => 0 
     2 => 7 % 5 => 2 
     3 => 0 % 5 => 0 
+0

這通常是一個好主意,但是我的數組並沒有相同的大小。更準確地說,該中心具有_a_ x_a_ elemens,左右數組具有_b_ x _a_元素,頂部和底部數組_a_ x _b_元素和其他四個元素(左上角,右上角......)的大小的_b_ x _b_。因此,我不能簡單地將索引除以一個數組的寬度或高度。 –

+0

是b djna

+0

如果b> a,也可以想出一個很好的算術方法。我會在明天再回答。總結:首先除以(a + b),然後用b除結果。 – djna