1

所以我今天花了几个小时写逻辑,把它变成代码,但我完全卡在这一点上,我不知道该怎么办。我现在才用 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 并继续。帮助?对于糟糕的格式感到抱歉,这个网站在粘贴代码方面并没有太大帮助......:|

4

1 回答 1

5

You're not clear about what's wrong with your code; it would be better to be explicit about what behavior you want and what behavior you are observing and where specifically you are stuck in making them match.

However, I suggest that you start by working on printing a simply number spiral pattern. From the Wikipedia article on the Ulam spiral, the basic spiral looks like this:

number spiral

A little study of the spiral shows some interesting properties. Starting from the center (where "1" is printed), going down and to the right on the diagonal you see all the odd squares in sequence. (Each row save the last extends one past the square, to include (2k+1)2+1.) Likewise, going up and to the left on the diagonal you see all the numbers of the form (2k)2 + 1 (one plus the even squares). You can use these properties to calculate the bounds of each row of the spiral.

Suppose you want to print 2N+1 rows and columns of the spiral (in the figure, N=3). Let the center row be row 0, column 0, so row and column indices range from -N to +N (inclusive). It makes sense to imagine a (2N+1) × (2N+1) matrix of cells. Our job is to decide how to fill in this matrix.

At this point, there are a couple of ways to approach the problem. In one approach, you fill it in by deciding where each integer 1, 2, ..., etc. goes, starting with "1" going at cell (0, 0). The other approach is to decide, for each cell (c, r), what integer goes in it.

Let's take the latter approach. We can observe the following properties for row r:

r ≤ 0

  • the number on the main diagonal on row r is (2r)2+1. This is at coordinates (r, r) from the center.
  • there are 1-2r connected numbers in sequence on row r (recall that r <= 0), going left-to-right in descending order from cell (r, r) through cell (-r, r). (For example, for r=-1, the sequence is "5—4—3" at cells (-1, -1), (0, -1), (1, -1).)
  • there are 2N+1 numbers on every row, which leaves (N+r) numbers to the left and right of the connected sequence.
  • for each cell (c, r) on row r with c < r (≤ 0), the number is obtained by adding r-c to the number at cell (c, c) (which, from above, is (2c>2+1).
  • for each cell (c, r) on row r with c > -r, the number is obtained by adding c+r to the number at cell (c, c) (which, from the first rule below, is (2c+1)2).

r ≥ 0

  • the number on the main diagonal on row r is (2r+1)2.
  • for r < N, there are 2r+2 connected numbers in sequence on row r, in going left-to-right in ascending order from cell (-r, r) through cell (r, r+1). (For example, "7—8—9—10".) On the last row (r=N), there are only 2N+1 connected numbers, since that's where we truncate the spiral.
  • there are 2N+1 numbers on every row, which leaves (N-r) numbers to the left and (N-r-1) numbers to the right of the connected sequence.
  • for each cell (c, r) on row r with c < -r, the number is obtained by adding r-c to the number at cell (c, c).
  • for each cell (c, r) on row r with c > r+1, the number is obtained by adding c-r to the number at cell (c, c).

From these rules, you should be able to create an algorithm to print out a spiral for any N > 0. I haven't addressed the issue of vertical connections between cells, but you can apply a similar analysis to discover the rules for drawing them. For proper formatting, you should pick a fixed width for each cell (which, obviously, should be wide enough for the largest number, (2N+1)2).

于 2013-05-05T18:00:17.073 回答