如何在C#中有效地将1D阵列复制到3D阵列?

时间:2014-11-04 12:32:20

标签: c# arrays

我有一个线性数组,我需要重塑一堆二维数据。在这种特殊情况下,堆栈只包含一个元素,因此输出应该是一个维度(高度,宽度,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#中使用?

2 个答案:

答案 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();
    }
}