如何在java中创造一个ulam螺旋?

时间:2013-05-05 04:21:50

标签: java spiral

所以今天我花了几个小时写出逻辑,把它变成代码,但是我完全陷入了困境,我不知道该怎么办。我现在只用java编程了几个月,所以整个“逻辑”思维方式还没有完全实现。任何人都可以帮助我思考如何在java中创建ulam螺旋的逻辑吗?

import java.util.Arrays;

public class GridMaker {
    private static int gridRow = 5; // R = length
    private static int gridCol = 5; // C = height
    private static int[][] grid = new int[gridRow][gridCol];
    private static int totalSteps = (gridRow * gridCol); // total blocks on the grid
    private static int location = 1; // location refers to the number in the box, ie. 1, 2, 3, etc.
    private static int rowLength = 1;

    public static void main(String[] args) {
        grid[Calc.findArrayCenter(gridRow)][Calc.findArrayCenter(gridRow)] = 1;
        rowBrowser();
        colBrowser();

    for (int r = 0; r < gridRow; r++){
        for (int c = 0; c < gridCol; c++){
            System.out.print(grid[r][c] + " ");
        }
        System.out.println("");
    }
}

public static void rowBrowser() {
    int rowCount = 1;
    int x = 1;
    int stepsInvolved = 2;

    if (x < stepsInvolved) {
        if (Calc.isOdd(rowCount) == true) {
            grid[Calc.findArrayCenter(gridRow)][Calc.findArrayCenter(gridCol) + x] = location + 1;
            stepsInvolved++;
        }
    }
    location++;
    x++;
}

private static void colBrowser() {

}
}

    public class Calc {
public static int findArrayCenter(int center) {
    int fcenter = 0;
    if (center % 2 != 0)
        fcenter = (int) ((center / 2));
    else
        fcenter = (center / 2);
    return fcenter;
}

public static boolean isOdd(int num) {
    boolean result = true;
    if (num % 2 == 0)
        result = false; // false = even, true = odd
    return result;
}
}

此时,我需要做些什么才能完成ulam螺旋?我现在正在做的是让数组跟踪一个位置,遍历一行中的每一步,然后下拉并运行一列中的步骤,然后向每个计数器添加1并继续。救命? 抱歉可怕的格式化,这个网站在粘贴代码时没有那么多帮助......:|

1 个答案:

答案 0 :(得分:5)

你不清楚你的代码有什么问题;最好明确一下你想要什么样的行为以及你正在观察什么样的行为,以及你在哪些方面让它们匹配。

但是,我建议您首先打印一个简单的数字螺旋图案。从Wikipedia article on the Ulam spiral开始,基本螺旋看起来像这样:

number spiral

对螺旋的一点研究表明了一些有趣的特性。从中心开始(打印“1”),在对角线上向下和向右,您可以看到所有奇数正方形。 (每行保存最后一个延伸超过正方形,包括(2k + 1) 2 +1。)同样,在对角线的左上方,你会看到表格的所有数字(2k) 2 + 1(一加偶数平方)。您可以使用这些属性来计算螺旋的每一行的边界。

假设您要打印2N + 1行和螺旋列(在图中,N = 3)。设中心行为第0行,第0列,因此行和列索引的范围为-N到+ N(含)。想象一下(2N + 1)×(2N + 1)个细胞矩阵是有意义的。我们的工作是决定如何填写这个矩阵。

此时,有几种方法可以解决这个问题。在一种方法中,您可以通过决定每个整数1,2,......等的位置来填充它,从单元格(0,0)处的“1”开始。另一种方法是为每个单元格(c,r)决定其中的整数。

让我们采取后一种方法。我们可以观察到行r的以下属性:

r≤0

  • 行r上主对角线上的数字是(2r) 2 +1。这是在距离中心的坐标(r,r)处。
  • 在行r上依次存在1-2r连接数(回想r <= 0),从单元(r,r)到单元(-r,r)以从左到右的顺序从左到右。 (例如,对于r = -1,序列在单元格(-1,-1),(0,-1),(1,-1)处为“5-4-3”。)
  • 每行有2N + 1个数字,在连接序列的左侧和右侧留下(N + r)个数字。
  • 对于行r上的每个单元(c,r),其中c <1。 r(≤0),该数字是通过将r-c加到单元格(c,c)上的数字得到的(从上面看,是(2c> 2 +1)。
  • 对于行r上的每个单元(c,r),其中c> 1。 -r,通过将c + r加到单元格(c,c)处的数字来获得数字(从下面的第一个规则,是(2c + 1) 2 )。

r≥0

  • 第r行主对角线上的数字是(2r + 1) 2
  • 表示r&lt; N,在行r上依次存在2r + 2个连接数,从单元(-r,r)到单元(r,r + 1)从左到右依次递增。 (例如,“7-8-9-10”。)在最后一行(r = N),只有2N + 1个连接数字,因为那是我们截断螺旋的位置。
  • 每行有2N + 1个数字,左边是(N-r)个数字,连接序列右边是(N-r-1)个数字。
  • 对于行r上的每个单元(c,r),其中c <1。 -r,通过将r-c添加到单元格(c,c)处的数字来获得该数字。
  • 对于行r上的每个单元(c,r),其中c> 1。 r + 1,通过将c-r加到单元格(c,c)处的数字来获得该数字。

根据这些规则,您应该能够创建一个算法来打印任何N&gt;的螺旋。 0.我没有解决单元格之间垂直连接的问题,但您可以应用类似的分析来发现绘制它们的规则。为了正确格式化,你应该为每个单元格选择一个固定的宽度(显然,对于最大的数字,它应该足够宽,(2N + 1) 2 )。