我有一个线性数组,我需要重塑一堆二维数据。在这种特殊情况下,堆栈只包含一个元素,因此输出应该是一个维度(高度,宽度,1)的数组。
这与previous question有关,我在那里询问另一个方向(3D到1D)的相同操作。
将此数据映射到3D阵列的最快方法是什么?
我打算采取以下方法:
public static byte[, ,] ToBuffer3D<TDepth>(this byte[] buffer, int w, int h)
{
byte[, ,] buff3D = new byte[h, w, 1];
for (int i = 0; i < buffer.Length; i++)
{
buff3D[(int)Math.Floor(i / (double)w), i % w, 0] = buffer[i];
}
return buff3D;
}
但似乎有可能利用数据如何已经存储在内存中来一次复制多个元素。是否有其他映射方法可以在C#中使用?
答案 0 :(得分:1)
这可能会更快一些:
public static byte[,,] ToBuffer3Da(this byte[] buffer, int w, int h)
{
byte[,,] buff3D = new byte[h, w, 1];
Buffer.BlockCopy(buffer, 0, buff3D, 0, h*w);
return buff3D;
}
答案 1 :(得分:1)
如果使用下面定义的基类和实现,则您有一个同时支持线性和维度索引的类。不需要转换或复制。
像这样使用,
var matrix = new DecomposedMatrix<byte>(10, 10, 10)
foreach(var b int matrix)
{
...
}
for (var i = 0; i < matrix.Count; i++)
{
...
var item = matrix[i];
...
}
for (var x = 0; x < matrix.H; x++)
for (var y = 0; y < matrix.W; y++)
for (var z = 0; z < matrix.D; z++)
{
...
var item = matrix[x, y, z];
...
}
课程遵循......
public abstract class DecomposedMatrix
{
private readonly int h;
private readonly int w;
private readonly int d;
protected DecomposedMatrix(int h, int w, int d)
{
this.h = h;
this.w = w;
this.d = d;
}
public int W
{
get
{
return this.w;
}
}
public int D
{
get
{
return this.d;
}
}
public int H
{
get
{
return this.h;
}
}
protected int DereferenceCoordinates(int x, int y, int z)
{
if (x >= this.H || y >= this.W || z >= this.D)
{
throw new IndexOutOfRangeException();
}
if (x < 0 || y < 0 || z < 0)
{
throw new IndexOutOfRangeException();
}
return z + (y * this.D) + (x * this.W * this.D);
}
}
和实施
public class DecomposedMatrix<T> : DecomposedMatrix, IReadOnlyList<T>
{
private readonly IList<T> data;
public DecomposedMatrix(int h, int w, int d)
: base(h, w, d)
{
this.data = new T[h * w * d];
}
public T this[int index]
{
get
{
return this.data[index];
}
set
{
this.data[index] = value;
}
}
public T this[int x, int y, int z]
{
get
{
return this.data[this.DereferenceCoordinates(x, y, z)];
}
set
{
this.data[this.DereferenceCoordinates(x, y, z)] = value;
}
}
public int Count
{
get
{
return this.data.Count;
}
}
public IEnumerator<T> GetEnumerator()
{
return this.data.GetEnumerator();
}
public IEnumerator IEnumerable.GetEnumerator()
{
return this.data.GetEnumerator();
}
}