c#将1维数组分配给具有移位值的2维数组

时间:2013-11-01 20:55:45

标签: c# arrays

我有一个双值的向量(1D数组),比如X.我需要将这个值向量复制到一个矩阵(2D数组)中,比如Y,这样Y的第一行与X转置相同,第二行与X向左移动一个值相同,Y的第三行与X相同,向左移动两个值,依此类推。

例如,

X = { 1.0, 2.0. 3.0, 4.0, 5.0 }

我需要

Y =  1.0  2.0  3.0  4.0  5.0
     2.0  3.0  4.0  5.0  0.0
     3.0  4.0  5.0  0.0  0.0
     4.0  5.0  0.0  0.0  0.0
     5.0  0.0  0.0  0.0  0.0

前段时间,Mathew Finlay发布了将1D数组复制到2D数组以获取值类型的代码。我修改了代码如下:

for (int targetRow = 0; targetRow < N; targetRow++)
{
    Buffer.BlockCopy
    (
        X,                                                    // 1D source array
        0,                                                    // source array offset
        Y,                                                    // 2D target (destination) array
        targetRow * Y.GetLength(targetRow) * sizeof(double),  // target array offset
        X.Length * sizeof(double)                             // count
    );
}

我不确定这是否能解决问题,更重要的是,这是否是最好的方法。这是更大代码的一部分,这部分需要快速有效,因为向量X和矩阵Y可以变得非常大。

另外,为了使事情复杂化,我可能不需要矢量X的全长(所有值)而只需要它的一部分,因此矩阵Y可以是N×M,其中M <= N.I我不知道如何处理上面的代码。

提前感谢您提供的任何帮助或建议。

编辑: 对于那些感兴趣的人,这里有一些表现结果。

我对这里建议的两种代码(循环和Buffer.BlockCopy)运行了一些速度测试,结果让我感到惊讶。我将Buffer.BlockCopy指定为BC并循环为L.对于10x10矩阵BC = 00:00:00.0000017和L = 00:00:00.0000030。对于100x100矩阵BC = 00:00:00.0000293和L = 00:00:00.0000710。最后,对于1000x1000矩阵BC = 00:00:00.0065340并且L = 00:00:00.0138396。因此,即使对于小矩阵,Buffer.Block副本似乎也优于循环。我在Win 7 Ultimate(64)机器上运行它。

2 个答案:

答案 0 :(得分:1)

怎么样?

       double[] X = new double[]{ 1.0, 2.0, 3.0, 4.0, 5.0 };

        var lbound = X.GetLowerBound(0);
        var ubound = X.GetUpperBound(0);

       double[,] Y = new double[ubound + 1, ubound + 1];

       for (var i = lbound; i <= ubound; i++)
       {
           for (var j = lbound ; j <= ubound ; j++)
           {
               Y[i, j] = (i + j) > ubound ? 0.0 : X[i +j];
           }  
       }

修改

这有效:

 for (int targetRow = 0; targetRow <= ubound; targetRow++)
  {
    Buffer.BlockCopy
    (
        X,                                        // 1D source array
        targetRow * sizeof(double),               // source array offset
        Y,                                        // 2D target (destination) array
        (targetRow * X.Length) * sizeof(double),  // target array offset
        (X.Length - targetRow) * sizeof(double)  // count
    );
}


for (var i = 0; i <= ubound; i++)
{
    for (var j = 0; j <= ubound; j++)
    {
        Console.Write(Y[i, j] + " ");
    }
    Console.WriteLine();
}

Console.ReadKey();

Array Offset


第二次编辑

要处理更改目标数组第二维的其他要求,您需要更改部分BlockCopy参数targetArrayOffsetcount,您可以将它们映射到维度目标数组如下所示。

        double[] X = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };

        var lbound = X.GetLowerBound(0);
        var ubound = X.GetUpperBound(0);

       double[,] Y = new double[X.Length, 3];

        int yLen = Y.GetUpperBound(1) + 1;

for (int targetRow = 0; targetRow <= ubound; targetRow++)
{
    Buffer.BlockCopy
    (
        X,                                      // 1D source array
        (targetRow * sizeof(double)),             // source array offset
        Y,                                        // 2D target (destination) array
        ((targetRow * yLen) * sizeof(double)),// target array offset
        ((X.Length - targetRow) > yLen ? yLen : (X.Length - targetRow))  * sizeof(double)  // count
    );
}

输出:

ScreenPrint

答案 1 :(得分:0)

假设x的类型为double[],请使用:

var y = new double[x.Length, x.Length];
for (int row = 0; row < x.Length; ++row)
{
  for (int col = 0; col < x.Length - row; ++col)
  {
    y[row, col] = x[col - row];
  }
}

或类似。