C#在2d大数组中找到2D小数组

时间:2017-02-15 13:19:45

标签: c# arrays multidimensional-array

    int[,] data = new int[,] {
        { 0, 0, 0, 0, 0 },
        { 0, 0, 1, 0, 0 },
        { 0, 1, 1, 0, 0 },
        { 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0 },
    };
    int[,] find = new int[,] {
        { 0, 1 },
        { 1, 1 }
    };

    bool result = Check2DArray (data, find);

如何在大型2D阵列中搜索小型2D阵列?

5 个答案:

答案 0 :(得分:2)

创建一个帮助方法,检查一个大数组是否包含从给定位置(row, col)开始的小数组。制作两个嵌套循环来迭代小数组可以匹配的大数组中的所有(row, col)对,并查看是否有任何一对会产生匹配。

static bool EqualAtPosition(int[,] big, int[,] small, int row, int col) {
    var rowCount = small.GetLength(0);
    var colCount = small.GetLength(1);
    if (row+rowCount > big.GetLength(0) || col+colCount > big.GetLength(1)) {
        return false;
    }
    for (var r = 0 ; r != rowCount ; r++) {
        for (var c = 0 ; c != colCount ; c++) {
            if (big[row+r, col+c] != small[r, c]) {
                return false;
            }
        }
    }
    return true;
}

答案 1 :(得分:2)

您可以尝试以下代码段:

static bool Check2DArray(int[,] data, int[,] find)
{
    int dataLen = data.Length; // length of the whole data
    int findLen = find.Length; // length of the whole find

    for(int i = 0; i < dataLen; i++) // iterate through data
    {
        int dataX = i % data.GetLength(0); // get current column index
        int dataY = i / data.GetLength(0); // get current row index

        bool okay = true; // declare result placeholder for that check
        for (int j = 0; j < findLen && okay; j++) // iterate through find
        {
            int findX = j % find.GetLength(1); // current column in find
            int findY = j / find.GetLength(1); // current row in find

            int checkedX = findX + dataX; // column index in data to check
            int checkedY = findY + dataY; // row index in data to check

            // check if checked index is not going outside of the data boundries 
            if ( checkedX >= data.GetLength(0) || checkedY >= data.GetLength(1))
            {
                // we are outside of the data boundries
                // set flag to false and break checks for this data row and column
                okay = false;
                break; 
            }

            // we are still inside of the data boundries so check if values matches
            okay = data[dataY + findY, dataX + findX] == find[findY, findX]; // check if it matches
        }
        if(okay) // if all values from both fragments are equal
            return true; // return true

    }
    return false;
}

您可以查看online here

请给我一些反馈,如果不够清楚,我可以详细解释:)

编辑:
发现此方法未检查data参数中的最后一行和列的问题。现在经过小修,一切都完美无缺。

EDIT2: 感谢@SefaTunçkanat指出我的错误。某些计算存在问题,可能导致IndexOutOfRange例外并比较错误的输入。现在一切正常。

答案 2 :(得分:2)

基本上你只是循环所有&#34;开始&#34;较小阵列可以适合较大阵列的位置,然后循环遍历较小阵列的值并与较大阵列中的相对位置进行比较,如果没有匹配则需要继续到较大阵列中的下一个位置数组,或者如果所有匹配都可以返回true,如果您在没有找到匹配的情况下完成更大的数组,那么您将返回false

public static bool Check2DArray(int[,] data, int[,] find)
{
    for (int dRow = 0; dRow < data.GetLength(0) - find.GetLength(0); dRow++)
    {
        for (int dCol = 0; dCol < data.GetLength(1) - find.GetLength(1); dCol++)
        {
            bool found = true;

            for (int fRow = 0; fRow < find.GetLength(0); fRow++)
            {
                for (int fCol = 0; fCol < find.GetLength(1); fCol++)
                {
                    if (data[dRow + fRow, dCol + fCol] != find[fRow,fCol])
                    {
                        found = false;
                        break;
                    }
                }

                if (!found) break;
            }

            if (found) return true;
        }
    }

    return false;
}

如果您愿意,也可以使用@dasblinkenlight的解决方案来替换内部的两个循环。

答案 3 :(得分:1)

根据数组的大小和您的要求,简单的强力算法就足够了。

你将从你的大数组中的[0,0]开始,检查这个坐标上的所有项是否都等于小数组中的项。 如果他们是你找到了匹配。如果不是,你会去大阵列中的下一个位置。

答案 4 :(得分:1)

  1. 在[0,0]处取小数组的第一个元素(让我们称之为start_e

  2. 通过大数组运行2个for循环

  3. 如果您发现start_e从较小的子阵列中复制子阵列并且

  4. 将它与可以检查2个相同大小的数组的帮助方法进行比较。