将3维数组转换为2维数组

时间:2014-09-09 10:51:27

标签: c# arrays flatten

我有这个字节数组:

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压平(因为我听说操作起来更快)。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

优化这一点的难点在于您想要省略的字节位于最“快速移动”的索引中。

我的意思是:如果为每个数组元素分配连续的数字,如下所示:

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)使用{{1}做一些发布构建的仔细时间确保使用不安全的代码确实值得。

还要注意使用不安全代码的缺点!不安全的代码需要提升权限,并且可能导致程序崩溃,导致低级C ++风格的指针错误!

Stopwatch

我个人认为使用简单,安全的循环不会太慢,但现在至少你有一些代码可以尝试。