Java在逻辑上连接数组
我有几个以不同组合出现的二维数组,其中一个定义了中心,另外八个逻辑(而非物理上)放置在左侧,右侧,顶部,右上角等等。 '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;
}
的问题是,由于这种方法的许多人呼吁我的整个程序是相当慢。我想知道是否有更好的方法来做到这一点。我想到了一些有效的方法来将索引转换为单个数组的内存地址,以获得一个新数组(因为数组访问完成得相当快)。
您可以通过一些简单(因此快速)的算术运算来映射坐标。任何其他边界检查都不需要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
阵列内,将其卸载到一个线程的帮助? –
阵列或其放置位置更改的频率以及您访问“放置配置”的频率? – Robert
除了手动编码所有情况下繁琐的手动编码之外,所显示的代码不一定很慢。使用分析器查找使用频率和瓶颈。 FindBugs也可能会产生一些影响。 –