用平面向量表示的网格扫描(遍历)

时间:2015-03-05 14:40:17

标签: algorithm

我有一个用平面向量表示的网格,即:

-------------
| 6 | 7 | 8 |
-------------
| 3 | 4 | 5 |
-------------
| 0 | 1 | 2 |
-------------

我访问索引从0到grid.size()-1的元素。我想实现快速扫描方法。该方法的主要目的是它sweeps,即特定方向的网格遍历。对于2D案例:

扫一扫:右上方

for [row = 0 : nrows-1]
    for [col = 0 : ncols-1] --> Result: 0 1 2 3 4 5 6 7 8

扫描2 :左上角

for [row = 0 : nrows-1]
    for [col = ncols-1 : 0] --> Result: 2 1 0 5 4 3 8 7 6

扫3 :右下角

for [row = nrows-1 : 0]
    for [col = 0 : ncols-1] --> Result: 6 7 8 3 4 5 0 1 2

扫4 :左下角

for [row = nrows-1 : 0]
    for [col = ncols-1 : 0] --> Result: 8 7 6 5 4 3 2 1 0 

然后计算idx = row*ncols + col

这种实现非常简单,只需嵌套n循环,它也可以推广到for维度。但是,我正在研究一个n维实现,我试图在2个循环中概括它:

while (keepSweeping)
    ++sweep;
    for (idx = init, idx == end, idx += inc)
         // Traverse the grid

计算initendinc真的很有挑战性。此外,inc取决于ncols并动态更改。例如,对于扫描2 inc = -1,但每ncolsinc = -1 + 2*ncols,所以我实现从0到5。

有关如何操作的任何帮助?我首先关注2D案例。

编辑:我看到这些线程http://www.cplusplus.com/forum/beginner/68434/ variable nested for loops建议以递归方式实现循环。既然我在寻找最佳性能,你认为这是一个好主意吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

好的,这是我尝试在2D情况下回答你的问题,只使用一个循环。希望这与你想要的并不太远:

// ****** INITIALIZATION ******
int ncols = 4; // number of columns
int nrows = 3; // number of rows
boolean right = true; // direction of sweep on horizontal axis
boolean top = true; // direction of sweep on vertical axis
int counter = 0; // number of positions explored
if (right) {
    colIterator = 0;
}
else {
    colIterator = ncols - 1;
}
if (top) {
    rowIterator = 0;
}
else {
    rowIterator = nrows - 1;
}

// ****** CONTINUATION CONDITION ******
while (counter != nrows*ncols) {

    // ****** DO SOMETHING ******
    System.out.println(rowIterator*ncols + colIterator);

    // ****** PROGRESSION PHASE ******
    counter++;
    // Have we completed a row?
    if ((counter % ncols) == 0) {
        if (top) {
            // We have to move up
            rowIterator++;
        }
        else {
            // we have to move down
            rowIterator--;
        }
        if (right) {
            colIterator = 0;
        }
        else {
            colIterator = ncols - 1;
        }
    }
    else {
        // We have not yet completed a row
        if (right) {
            // We have to move right
            colIterator++;
        }
        else {
            // or left
            colIterator--;
        }
    }
}

注意:此代码已经过Groovy测试。

一些上层解释:它适用于一个循环,因为在2D中,我们可以找到我们想要做的工作的进展的全局指标(此度量标准是counter变量)并且可以使用度量来在循环的每次迭代中确定是否通过使用模数操作完成了一行(或不是)

我不认为在数学上可以将此算法推广到只有一个循环的上维度(即2以上),因为没有数学运算符可以告诉我们是否已完成部分工作在一个给定的维度上,应该开始处理 outter维度(这里,模数告诉我们必须修改rowIterator,因为我们已经到达边界对于网格,但在维度3 或以上3,使用的数学运算符是什么?)。

祝你好运,请发布你发现的内容,这是一个有趣的挑战。