簡體   English   中英

將3維數組轉換為2維數組

[英]convert 3 dimensional array to a 2 dimensional array

我有這個字節數組:

byte[,,] somedata = new byte[100,150,3];
~somedata is now populated by an external input.

我只想在其中使用這些值:

byte[,] useThisDataOnly = new byte[100,150];

目前,我使用這個:

foreach (int x=0,x< 100; x++)
{
    foreach (int y=0,y< 150; y++)
    {
       useThisDataOnly [x,y] = somedata[x,y,0];
    }
}

有沒有一種更快的方法呢?

另外,我將把這個useThisDataOnly扁平化(據我所知,它的處理速度更快)。

有什么建議么?

優化這一點的困難在於,要忽略的字節位於最“快速移動”的索引中。

我的意思是:如果像這樣給每個數組元素分配連續的數字:

byte[,,] source = new byte[100, 150, 3];

for (int i = 0, n = 0; i < 100; ++i)
    for (int j = 0; j < 150; ++j)
        for (int k = 0; k < 3; ++k, ++n)
            source[i, j, k] = unchecked ((byte)n);

如果按展平的順序打印內容,將得到0..255重復。

然后,您排除最終尺寸:

for (int i = 0; i < 100; ++i)
    for (int j = 0; j < 150; ++j)
        dest[i, j] = source[i, j, 0];

如果按展平的順序打印結果,將得到:

0, 3, 6, 9, 12, 15, ...

因此,您可以看到為了將輸入轉換為輸出,您需要占用每個第三個字節,但是不幸的是,沒有快速的方法可以做到這一點。

但是,如果您能夠要求創建的數組首先要省略索引:

byte[,,] source = new byte[3, 100, 150];

那么您可以使用Buffer.BlockCopy()

我猜這不是一個選擇-否則,手動編碼循環可能是最快的方法,而無需訴諸不安全的代碼。

不安全的代碼

這是使用不安全的代碼和指針的方法。 這甚至可能無法使其更快,因此在選擇執行此操作之前,您需要(a)確保執行簡單的方法確實太慢,並且(b)使用Stopwatch進行發布構建的一些謹慎時機以確保確實值得使用不安全的代碼。

還應注意使用不安全代碼的弊端! 不安全的代碼需要提升的權限,並且可能會導致您的程序由於低級C ++風格的野生指針錯誤而崩潰!

using System;
using System.Diagnostics;

namespace Demo
{
    internal static class Program
    {
        static void Main()
        {
            byte[,,] source = new byte[100, 150, 3];

            for (int i = 0, n = 0; i < 100; ++i)
                for (int j = 0; j < 150; ++j)
                    for (int k = 0; k < 3; ++k, ++n)
                        source[i, j, k] = unchecked ((byte)n);

            byte[,] dest1 = new byte[100, 150];
            byte[,] dest2 = new byte[100, 150];

            for (int i = 0; i < 100; ++i)
                for (int j = 0; j < 150; ++j)
                    dest1[i, j] = source[i, j, 0];

            unsafe
            {
                fixed (byte* sp = source)
                fixed (byte* dp = dest2)
                {
                    byte* q = dp;
                    byte* p = sp;

                    for (int i = 0; i < 100*150; ++i)
                    {
                        *q++ = *p;
                        p += 3;
                    }
                }
            }

            for (int i = 0; i < 100; ++i)
                for (int j = 0; j < 150; ++j)
                    Trace.Assert(dest1[i, j] == dest2[i, j], "Arrays should be identical");
        }
    }
}

我個人認為使用簡單,安全的循環不會太慢,但是現在至少您可以嘗試一些代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM