【问题标题】:Algorithm to create a diagonal pattern through a n x n grid通过 n x n 网格创建对角线图案的算法
【发布时间】:2014-02-22 18:52:24
【问题描述】:

我想知道解决标题中列出的问题的算法的名称,或者解释如何做到这一点,我会尽量仔细解释,考虑一下:

9 8 6
7 5 3
4 2 1

它表示一个 3 x 3 的网格,我想按照此处注明的顺序遍历网格。右下为原点 (0, 0),左上为 (2, 2)。

所以在坐标中遍历看起来像:

  1. (0, 0) [1 级]
  2. (1, 0) [2 级]
  3. (0, 1) [2 级]
  4. (2, 0) [3 级]
  5. (1, 1) [3 级]
  6. (0, 2) [3 级]
  7. (2, 1) [4 级]
  8. (1, 2) [4 级]
  9. (2 ,2) [5 级]

级别表示某种迭代。

此外,如果可以使用 java 甚至 java 8 以一种很好的方式生成它,那么我会很高兴看到它,因为我认为它作为一种幼稚的循环方法更好。

我想用它来为图形应用程序生成地形,就像传统的迭代方法(循环宽度,循环深度)一样,它会创建“奇怪的”随机模式,至少不是我想要的。

给定输入n,我想我对伪代码有一个想法:

while x < 2 && y < 2
do
    "iterate over elements to the top right if they exist"
    if (x < 2) x++
    else
        if (y < 2) y++

这将导致预期的迭代。

【问题讨论】:

  • 这种简单程度的算法不会有名称。
  • 到目前为止你有什么?

标签: java algorithm math language-agnostic grid


【解决方案1】:

你可以做的是两组双重嵌套循环,首先做左下三角形和对角线。然后是右上角的三角形。你可以看到这是一个小提琴http://jsfiddle.net/SalixAlba/76zdLbp7/

var size=5;
var x=0;
var y=0;

// Set up data array, store the index of the point
var data = new Array(size);
for(var i=0;i<size;++i) {
    data[i]=new Array(size);
}

var pos=1;
// Bottom right triangle
for(var i=0;i<size;++i) { // should be size
    for(var j=0;j<=i;++j) {
        x = size - i + j - 1;
        y = size - j - 1;
        data[y][x] = pos;
        console.log(i,j,x,y);        
        ++pos;
    }
}

// Top left triangle
for(var i=0;i<size-1;++i) {
    for(var j=0;j<size-1-i;++j) {
        x = j;
        y = size - i - j - 2;
        data[y][x] = pos;
        console.log(i,j,x,y);        
        ++pos;
    }
}

var res="";
for(var i=0;i<size;++i) {
    res = res + data[i].toString() + "\n";
}
$("textarea#output").val(res);

【讨论】:

    【解决方案2】:

    对于每个“递归级别”,每个A[i][j]i + j = n n 是递归级别,A 是包含您的网格的数组,您不只是想要吗? 像

    int[][] A = {{1,2,3},{4,5,6},{7,8,9}};
    for(int n=0;n < A.length + A[0].length;n++) {
      for (int i=0;i<=n;i++) {
        int j = n - i;
        if(i<A.length && j<A[0].length)
          System.out.print(A[i][j]+" ");
      }
      System.out.println();
    }
    

    有一个存在

    9 6 3
    8 5 2
    7 4 1
    

    你得到

    1
    2 4
    3 5 7
    6 8
    9
    

    每一行都是一个迭代层次

    【讨论】:

    • 关闭,但请考虑要打印多少项目。您可以省略 j 循环并从您的公式中计算 j = n - i。此外,正如您所指出的,您需要检查 j 是否位于网格内。
    • 更好,但它仍然会打印两倍的项目。通过使用 min,您将使用 j 的负索引来处理项目。在对A[i][j] 做任何事情之前,您应该检查0 &lt;= j &amp;&amp; j &lt; A[0].length) 而不是min
    • 我喜欢你在代码中区分两个维度的方式,但是如果你允许矩形矩阵,你的第一个循环应该运行到A.length + A[0].length而不是2*A.length
    • 我不明白,j=n-ii0变成nj怎么可能是负数?这不仅是重复的问题,我的代码在n&gt;A.length 时采用旧值(这不应该发生,我对其进行了编辑)。感谢n 的限制。
    • 好吧,试试你的代码。假设外部循环处于第一次迭代中,n 为 0。然后将 i 从 0 迭代到 length。问:i为1,n为0时,j的值是多少?
    【解决方案3】:

    您可以解决此问题的一种方法是将每个数字视为具有左侧和顶部邻居的单个节点。

    所以你的第一个级别如下:

     3
    21
    

    在请求节点时,您会将 1(0,0) 的坐标传递给它,然后返回 (x+1,y) 和 (x, y+1) 以给出两个邻居。

    然后您可以使用任何其他节点再次执行此操作以走不同的路径。

    下一级将由两个节点及其邻居组成,例如:

     6
    53  
    

     5
    42
    

    因此,对于第二级,当您传入节点 2 和 3 时,您将得到 4、5、5、6 作为结果,您可以在进入下一个级别之前过滤掉重复项。

    这里的关键是遍历节点列表:

    for(Node n: nodes)
    {
        Node left = new Node(n.x+1, n.y);
        Node top = new Node(n.x, n.y+1);
        //store these nodes in result list
    }
    

    使用包含 x 和 y 坐标的节点类(您必须自己制作该对象)。可能还有一种更优雅的方法来解决这个问题,但我只是想让你思考你正在解决的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多