Sliding window algorithm in C#

2019-02-20 17:00发布

问题:

I'm trying to implement simple sliding window alogirithm on two-dimensional array in C# 3.0, I found this as very useful but it involves only single-dimensioal array.

The post also includes the code for the algo, I'm totaly failed to use it for my senario... can any one suggest me how do I proceed?

Scenario:

http://parasu516.googlepages.com/matrix.jpg http://parasu516.googlepages.com/matrix.jpg

The above image is 10X10 matrix and need get 3X3 matrix out it, using any algorithm (Sliding window would be greate). Red rectangle is a first set and green one is the second. and it goes on till the end for all rows

PS: I googled about the algo, but no luck :(

回答1:

Naive implementation:

private static IEnumerable<T[,]> GetWindows<T>(
    T[,] array,
    int windowWidth,
    int windowHeight)
{
    for (var y = 0; y < array.GetLength(1) - windowHeight + 1; y++)
    {
        for (var x = 0; x < array.GetLength(0) - windowWidth + 1; x++)
        {
            var slice = new T[windowWidth, windowHeight];
            CopyArray(array, x, y, slice, 0, 0, windowWidth, windowHeight);
            yield return slice;
        }
    }
}

Helper method to copy between two-dimensional arrays:

private static void CopyArray<T>(
    T[,] src, int srcX, int srcY,
    T[,] dst, int dstX, int dstY,
    int width, int height)
{
    for (var x = 0; x < width; x++)
    {
        for (var y = 0; y < height; y++)
        {
            dst[dstX + x, dstY + y] = src[srcX + x, srcY + y];
        }
    }
}

Test main:

private static void Main(string[] args)
{
    var array = new string[5, 5];
    for (var y = 0; y < array.GetLength(1); y++)
    {
        for (var x = 0; x < array.GetLength(0); x++)
        {
            array[x, y] = string.Format("({0}|{1})", x, y);
        }
    }
    foreach (var window in GetWindows(array, 3, 3))
    {
        ShowArray(window);
    }
    Console.ReadLine();
}

private static void ShowArray<T>(T[,] array)
{
    for (var x = 0; x < array.GetLength(0); x++)
    {
        for (var y = 0; y < array.GetLength(1); y++)
        {
            Console.Write("    {0}", array[x, y]);
        }
        Console.WriteLine();
    }
    Console.WriteLine();
}

Output:

(0|0)    (0|1)    (0|2)
(1|0)    (1|1)    (1|2)
(2|0)    (2|1)    (2|2)

(1|0)    (1|1)    (1|2)
(2|0)    (2|1)    (2|2)
(3|0)    (3|1)    (3|2)

(2|0)    (2|1)    (2|2)
(3|0)    (3|1)    (3|2)
(4|0)    (4|1)    (4|2)

(0|1)    (0|2)    (0|3)
(1|1)    (1|2)    (1|3)
(2|1)    (2|2)    (2|3)

(1|1)    (1|2)    (1|3)
(2|1)    (2|2)    (2|3)
(3|1)    (3|2)    (3|3)

(2|1)    (2|2)    (2|3)
(3|1)    (3|2)    (3|3)
(4|1)    (4|2)    (4|3)

(0|2)    (0|3)    (0|4)
(1|2)    (1|3)    (1|4)
(2|2)    (2|3)    (2|4)

(1|2)    (1|3)    (1|4)
(2|2)    (2|3)    (2|4)
(3|2)    (3|3)    (3|4)

(2|2)    (2|3)    (2|4)
(3|2)    (3|3)    (3|4)
(4|2)    (4|3)    (4|4)

Now all you have to do is apply the same technique as shown in that blog post :)