2014-11-04 54 views
0

我有一個線性數組,我需要重新塑造一堆二維數據。在這種特殊情況下,堆棧只包含一個元素,所以輸出應該是一個具有維度(高度,寬度,1)的數組。如何在C#中有效地將1D數組複製到3D數組?

這與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#中使用?

+1

。做與你之前的問題相同的東西只是扭轉方向 – Hogan 2014-11-04 12:36:12

+1

可能的重複[如何將3D數組映射到線性數組?](http://stackoverflow.com/questions/26705659/how-to-map-a- 3d-array-to-a-linear-array) – Hogan 2014-11-04 12:36:21

+0

@dionys幸運的是,你就是這樣!如果你遵循我的建議,而不是做出尖銳的評論,那麼你已經有了最好的解決方案 – Hogan 2014-11-04 12:47:27

回答

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

,如果你使用的基類,實現如下定義的,你有在同一時間同時支持線性和二維索引類。不需要轉換或複製。

如果這樣下去,它會另外一個方式來使用它這個樣子,

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(); 
    } 
} 
相關問題