c# - 将二维数组的二维数组转换为单个二维数组

标签 c# arrays matrix multidimensional-array

所以我有一个对象,由于缺少更好的词,MatricesMatrix 它是矩阵的 Matrix(所有内容都存储为 double[, ])。我想将内部矩阵中的所有值剥离到一个大矩阵中。这是我目前所拥有的:

public Matrix ConvertToMatrix()
    {
        //Figure out how big the return matrix should be
        int totalRows = this.TotalRows();
        int totalColumns = this.TotalColumns();

        Matrix returnMatrix = new Matrix(totalRows, totalColumns);

        List<object> rowElementsList = new List<object>();

        //"outer" index means an index of the MatricesMatrix
        //"inner" index means an index of a Matrix within the Matrices Matrix

        //outer row loop
        for (int outerRowIndex = 0; outerRowIndex < NumberOfRows; outerRowIndex++)
        {
            //outer column loop
            for (int outerColumnIndex = 0; outerColumnIndex < NumberOfColumns; outerColumnIndex++)
            {
                Matrix currentMatrix = GetElement(outerRowIndex, outerColumnIndex);
                object element = null;

                //inner row loop
                for (int innerRowIndex = 0; innerRowIndex < currentMatrix.NumberOfRows; innerRowIndex++)
                {
                    //inner column loop
                    for (int innerColumnIndex = 0; innerColumnIndex < currentMatrix.NumberOfColumns; innerColumnIndex++)
                    {
                       element = currentMatrix.GetElement(innerRowIndex, innerColumnIndex);                          
                    }            
                }

                returnMatrix.SetElement(outerRowIndex, outerColumnIndex, (double)element);      





            }
        }

        return returnMatrix;
    }

请注意,我已经以编程方式确定了 returnMatrix 需要的行数和列数。

这里有一些更多的指南和输出案例:

  • 大矩阵的每个元素相对于来自该元素来自的 MatricesMatrix 内部的矩阵的大矩阵的其他元素应该处于相同的位置。
  • 大矩阵内的每个“矩阵”(不再是矩阵形式)相对于大矩阵内其他矩阵的位置应该与它在 MatricesMatrix 内的位置相同(没有重叠,并且 0's in任何空格留空)。

案例 1

给定此输入:MatricesMatrix(2,2) 具有 [0,0] = (2x2 矩阵), [0,1] = (2x3 矩阵), [1, 0] = (2x2 矩阵), [1,1] = (2x3 矩阵)。也就是说,

MatricesMatrix Input

输出必须是:

Output Case 2

案例 2

给定此输入:MatricesMatrix(2,2) 具有 [0,0] = (1x1 矩阵), [0,1] = (3x3 矩阵), [1, 0] = (2x2 矩阵), [1,1] = (4x4 矩阵)。也就是说,

Case 2 Input

输出应该是这样的:

Case 2 Output

如有任何帮助,我们将不胜感激!

更新: 这是应该通过的案例 1 的单元测试:

    [TestMethod]
    public void MatricesMatrix_ConvertToMatrixTest()
    {
        Matrix m1 = new Matrix(2);
        Matrix m2 = new Matrix(2, 3);
        Matrix m3 = new Matrix(2);
        Matrix m4 = new Matrix(2, 3);

        double[] m1Row1 = { 1, 1 };
        double[] m1Row2 = { 1, 1 };

        double[] m2Row1 = { 2, 2, 2 };
        double[] m2Row2 = { 2, 2, 2 };            

        double[] m3Row1 = { 3, 3 };
        double[] m3Row2 = { 3, 3 };

        double[] m4Row1 = { 4, 4, 4 };
        double[] m4Row2 = { 4, 4, 4 };

        m1.SetRowOfMatrix(0, m1Row1);
        m1.SetRowOfMatrix(1, m1Row2);
        m2.SetRowOfMatrix(0, m2Row1);
        m2.SetRowOfMatrix(1, m2Row2); 
        m3.SetRowOfMatrix(0, m3Row1);
        m3.SetRowOfMatrix(1, m3Row2);
        m4.SetRowOfMatrix(0, m4Row1);
        m4.SetRowOfMatrix(1, m4Row2);

        MatricesMatrix testMatricesMatrix = new MatricesMatrix(2, 2);

        testMatricesMatrix.SetElement(0, 0, m1);
        testMatricesMatrix.SetElement(0, 1, m2);
        testMatricesMatrix.SetElement(1, 0, m3);
        testMatricesMatrix.SetElement(1, 1, m4);

        Matrix expectedResult = new Matrix(4, 5);

        double[] expectedRow1 = { 1, 1, 2, 2, 2 };
        double[] expectedRow2 = { 1, 1, 2, 2, 2 };
        double[] expectedRow3 = { 3, 3, 4, 4, 4 };
        double[] expectedRow4 = { 3, 3, 4, 4, 4 };

        expectedResult.SetRowOfMatrix(0, expectedRow1);
        expectedResult.SetRowOfMatrix(1, expectedRow2);
        expectedResult.SetRowOfMatrix(2, expectedRow3);
        expectedResult.SetRowOfMatrix(3, expectedRow4);

        Matrix actualResult = testMatricesMatrix.ConvertToMatrix();

        (actualResult == expectedResult).Should().BeTrue();

    }

最佳答案

我从一个简单的 Matrix 类开始,用于保存 double[,]。没什么特别的,只是一个简单的数组数组,带有行数和列数以及数组访问器。

class Matrix<T>
{
    public int Rows { get; private set; }
    public int Cols { get; private set; }

    private T[,] mat;

    public Matrix(int rowCount, int colCount)
    {
        Rows = rowCount;
        Cols = colCount;
        mat = new T[Rows, Cols];
    }

    public T this[int r, int c]
    {
        get { return mat[r, c]; }
        set { mat[r, c] = value; }
    }
}

你的第二种情况看起来比第一种更难(并且更像是正确性测试),所以我设置了一个元矩阵来匹配它。

public static Matrix<double[,]> BuildMetaMatrix()
{
    Matrix<double[,]> m = new Matrix<double[,]>(2, 2);

    m[0, 0] = new double[,]
    {
        { 1 }
    };

    m[0, 1] = new double[,]
    {
        { 3, 3, 3 },
        { 3, 3, 3 },
        { 3, 3, 3 }
    };

    m[1, 0] = new double[,]
    {
        { 2, 2 },
        { 2, 2 }
    };

    m[1, 1] = new double[,]
    {
        {4, 4, 4, 4},
        {4, 4, 4, 4},
        {4, 4, 4, 4},
        {4, 4, 4, 4}
    };

    return m;
}

为方便起见,我制作了一个 Place 函数,可在给定位置将一个矩阵放入另一个矩阵。

static void Place(double[,] src, double[,] dest, int destR, int destC)
{
    for (int row = 0; row < src.GetLength(ROW_DIM); row++)
    {
        for (int col = 0; col < src.GetLength(COL_DIM); col++)
        {
            dest[row + destR, col + destC] = src[row, col];
        }
    }
}

输入 GetLength() 的魔数(Magic Number)只是为了找错,所以我为它们定义了一些常量(ROW_DIM = 0COL_DIM = 1)。我决定通过确定列的宽度和行的高度并在 Place() 插入子矩阵后跳过任何额外元素来处理填充。GetRowHeight() GetColWidth() 方法找出值。

public static int GetRowHeight(Matrix<double[,]> m, int row)
{
    int maxSeen = 0;

    for (int col = 0; col < m.Cols; col++)
    {
        if (m[row, col].GetLength(ROW_DIM) > maxSeen)
        {
            maxSeen = m[row, col].GetLength(ROW_DIM);
        }
    }

    return maxSeen;
}

public static int GetColWidth(Matrix<double[,]> m, int col)
{
    int maxSeen = 0;

    for (int row = 0; row < m.Rows; row++)
    {
        if (m[row, col].GetLength(COL_DIM) > maxSeen)
        {
            maxSeen = m[row, col].GetLength(COL_DIM);
        }
    }

    return maxSeen;
}

Flatten() 函数循环遍历所有子矩阵,Place()将它们放置在新矩阵中适当的行和列中。它使用 GetRowHeight()GetColWidth() 函数在每个 Place() 之后更新下一行和下一列。

Matrix<double> Flatten(Matrix<Matrix<double>> src)
{
    // (7, 6) == (this.TotalRows(), this.TotalColumns())
    // from your code.
    Matrix<double> dest = new Matrix<double>(7, 6);

    int nextRow = 0;
    int nextCol = 0;

    for (int row = 0; row < src.Rows; row++)
    {
        for (int col = 0; col < src.Rows; col++)
        {
            dest.Place(src[row, col], nextRow, nextCol);
            nextCol += GetColWidth(src, col);
        }
        nextRow += GetRowHeight(src, row);
        nextCol = 0;
    }

    return dest;
}

一点点胶水来测试一下......

static void Main(string[] args)
{
    Matrix<double[,]> src = BuildMetaMatrix();
    double[,] dest = Flatten(src);

    Print(dest);
    Console.ReadLine();
}

static void Print(double[,] matrix)
{
    for (int row = 0; row < matrix.GetLength(ROW_DIM); row++)
    {
        for (int col = 0; col < matrix.GetLength(COL_DIM); col++)
        {
            Console.Write(matrix[row, col] + "\t");
        }
        Console.Write("\n");
    }
}

...你得到的输出就像你的第二种情况,所有奇怪的拟合矩阵和空位的 0。*

1       0       3       3       3       0
0       0       3       3       3       0
0       0       3       3       3       0
2       2       4       4       4       4
2       2       4       4       4       4
0       0       4       4       4       4
0       0       4       4       4       4

*目标矩阵将其值初始化为 default(double),恰好是 0(您想要的值)。如果您需要 default(double) 以外的其他内容作为空位,您可以通过遍历新矩阵并在 Flatten() 之前的任何地方写入新的默认值来获得它们>正在处理元矩阵。

(感谢 Jeff Mercado 指出多维数组的 GetLength() 方法可用于查找它们的维度。)

关于c# - 将二维数组的二维数组转换为单个二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24678305/

相关文章:

matlab - Matlab错误使用错误-矩阵尺寸必须一致

c# - post 方法是否可以在继续该方法之前向用户返回确认框?

c# - 为什么编程方法中的try catch不起作用?

arrays - 使用结构体存储动态数据

数据集的剩余变量

matrix - Lua 中令人困惑的矩阵生成示例

c# - 如何在 Gtk# 中将上下文菜单添加到树节点?

c# - 哪个是 MSCorEE.h 在单声道编译器中的等效头文件?

无法理解 MPI 中的 MPI_Reduce_scatter

javascript - 如何使属性动态化(在执行代码之前未知)?