如何迭代网格算法

时间:2013-03-02 21:16:45

标签: c#

我正在寻找一种可以迭代网格并将其转换为另一个网格的算法,该网格的索引按新顺序排列。

基本上,给定一个大小为n * m的网格:

1_1 1_2 1_3 ... 1_n
2_1 2_2 2_3 ... 2_n
.
.
.
m_1 m_2 m_3 ... m_m

我怎样才能将其转换为:

1_1 1_2 1_4 ...
1_3 1_5 ...
1_6 ...
...
.
.
.

假设,您遍历第一个网格,然后在顶行中从左到右 在第二行中从左到右,一直到底行中从左到右。

基本上我将元素推入上三角。

另一个问题是如何通过知道n和m是什么来计算用于存储三角形的网格的长度和宽度? 那有一个公式吗?

例如,5 * 6的网格变为8 * 7 ...

1  2  3  4  5
6  7  8  9  10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30

变为:

 1  2  4  7  11 16 22 29
 3  5  8  12 17 23 30
 6  9  13 18 24
 10 14 19 25
 15 20 26
 21 27
 28

2 个答案:

答案 0 :(得分:2)

让我们在起始网格NxM中定义每个网格元素(i,j)的“序数位置”O(i,j),其是函数(i,j) - >我* N + j。

现在对于小于O(i,j)的最大三角数,对于某些k,将其称为T ==(k(k + 1)/ 2,我们(i,j)的新网格位置将为:  (i,j) - > (O(i,j) - T,k + T - O(i,j))


现在替换O(i,j)和T得到:

(i,j) - > (i * N + j - k(k + 1)/ 2,k +(k + 1)(k + 2)/ 2 - i * N + j)

=(i * N + j - k(k + 1)/ 2,(k + 1)(k + 2)/ 2 - i * N + j)


就我现在所能得到的那样。

<强>更新 再次注意,k是三角形数T == k(k + 1)/ 2的边长。

答案 1 :(得分:2)

以下似乎对我有用:

public static T[,] ConvertToUpperTriangle<T>(T[,] arr)
{
    // calculate the dimensions
    int elements = arr.GetLength(0) * arr.GetLength(1);

    double rows = 0.5 * (Math.Sqrt(8 * elements + 1) - 1);

    int newHeight = (int)rows;
    int newWidth = (int)Math.Ceiling(rows);

    // create the new array
    var arr2 = new T[newHeight, newWidth];

    int j = 0;
    int i = 0;
    foreach (T element in arr)
    {
        arr2[j, i] = element;
        i--;
        j++;
        if (i < 0)
        {
            i = j;
            j = 0;
        }
    }

    return arr2;
}

0.5 * (Math.Sqrt(8 * elements + 1) - 1)来自sum from 1 to n of n,然后是solve a = 0.5 * n * (n + 1) for nWolfram Alpha

修改

您可以按以下方式获取给定i的索引jindex

int rows = (int)(0.5 * (Math.Sqrt(8 * index + 1) - 1));

int bottomLeft = (int)(0.5 * rows * (rows + 1));
int difference = index - bottomLeft;

int i;
int j;

if (bottomLeft == index)
{
    i = 0;
    j = rows - 1;
}
else
{
    i = rows + 1 - difference;
    j = difference - 1;
}