Java Tournament计划递归

时间:2015-04-28 18:37:32

标签: java recursion

我正在为我的Java类做一个家庭作业,我仍然坚持如何设置递归(必需)以使其工作。我们必须提醒用户注意一些&n;竞争对手(假设它必须是2的幂,我们不需要检查有效的用户输入)。每支球队必须只参加一次其他球队。 n = 8的输出应为:

1  2  3  4  5  6  7  8
2  1  4  3  6  5  8  7
3  4  1  2  7  8  5  6
4  3  2  1  8  7  6  5
5  6  7  8  1  2  3  4
6  5  8  7  2  1  4  3
7  8  5  6  3  4  1  2
8  7  6  5  4  3  2  1

我允许传递给方法的唯一参数是' int n'。因此,如果有16支队伍(即n = 16),那么第二次调用将通过8,然后通过4,然后是2,最后是1。

所以,基于此,我认识到每一行都只是翻转每对数字。所以对于2 ^ 0,只有一个团队。对于2 ^ 1,它是:

1  2
2  1

对于2 ^ 2,它是4个团队,但是团队3和4具有与团队1和团队2相同的递归。然后,你交换它们以便3和4在1和2之前进行交换然后再次交换单个对:

1  2  3  4
2  1  4  3
3  4  1  2
4  3  2  1

所以你基本上可以将图表分成4个相等的角,每个对角相等。

在过去的几天里,我的代码经历了很多变化,但这就是我现在所处的位置。这实际上是从我的位置向后退了一步,但我原本试图通过一个起始行和一个开始col,但我被告知我不应该这样做,并且只是递归地传递n。

class MyArray {
    final int MAXROW = 32, MAXCOL = 32;
    int A[][]; //reference variable
    int nR, nC; //number of integers in A, <= MAXSIZE

//constructor
MyArray() {
    A = new int[MAXROW] [MAXCOL];
    nR = nC = 0;
}

void schedule(int n) {
        if (n > 1) {
            schedule(n/2);
            for (int r = 0; r < n/2; r++)
                for (int c = 0; c < n/2; c++) {
                    A[r+n][c] = A[r][c+n];
                    A[r+n][c+n] = A[r][c];
                 }
        }
    }
void printA() {
    printA(nC-1)
}

void printA(int n) {
    if (n >= 0) {
        printA(n-1);
        for (int c = 0; c < nC; c++)
            System.out.printf("%3d", (A[n][c]));
        System.out.println();
    }
}

3 个答案:

答案 0 :(得分:3)

终于明白了。这是调度方法的代码,漂亮,短而甜,基本上,左上角值+(n / 2)=右上角和左下角值。右下角值=左上角值。

void schedule(int n) {
    if (n > 0) {
        schedule(n/2);
        if (n == 1)
            A[0][0] = 1;
        else {
            for (int r = 0; r < n/2; r++)
                for (int c = 0; c < n/2; c++) {
                    A[r][c+(n/2)] = A[r][c] + (n/2);
                    A[r+(n/2)][c] = A[r][c] + (n/2);
                    A[r+(n/2)][c+(n/2)] = A[r][c];
                }
        }
    }
}

答案 1 :(得分:1)

我无法修复您的代码.....我的解决方案:

recursive

public class MyArray {

    final int MAXROW = 32, MAXCOL = 32;
    int A[][]; //reference variable

    MyArray() {
        A = new int[MAXROW][MAXCOL];
    }

    public static void main(String[] args) {
        MyArray m = new MyArray();
        int n = 8;
        m.mySchedule(n);
        m.printA(n);
    }

    void mySchedule(int n) {
        mySchedule(n, 0, 0, n);
    }

    void mySchedule(int n, int row, int col, int carry) {
        if (n == 1) {
            A[row][col] = carry; //Trivial Case
        } else {
            //divide the problem into 4 subproblems
            int k = n / 2;
            mySchedule(k, row, col, carry - k);
            mySchedule(k, row, col + k, carry);
            mySchedule(k, row + k, col, carry);
            mySchedule(k, row + k, col + k, carry - k);
        }
    }

    void printA(int n) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                System.out.print(A[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

答案 2 :(得分:0)

这是我当前的代码版本。我的教授仍然说通过删除第二次递归调用可以提高效率。我已经包含了所有的评论,所以我记得每件事实际上做了什么。

class MySchedule {
    final int MAXSIZE = 32;
    int A[][]; //reference variable
    int max; //number of integers in A, <= MAXSIZE
    int row = 1; //keeps track of rows during recursion, row 0 set during user input

    //constructor
    MySchedule() {
        A = new int[MAXSIZE] [MAXSIZE];
        max = 0;
    }

    /*
    if teams = 4, then movements per row are: 2^0, 2^1, 2^0
    if teams = 8: 2^0, 2^1, 2^0, 2^2, 2^0, 2^1, 2^0
    (n/2) gives us the correct power to calculate movements
    for each value of n, we move n places in either direction
    for loop iterates ever 2*n
    outer loop is for each iteration
    inner loops are each number of movements for each iteration
    */
    void schedule(int n) {
        if (n >= 1) {
            schedule(n/2);
            //start at column 0 for each row
            int col = 0;
            for (int i = 0; i < max; i += (2*n)) {
                //current position uses value from previous n rows/columns.
                for (int j = 0; j < n; j++)
                    A[row][col+j] = A[row-n][col+j+n];
                for (int j = n; j < n*2; j++)
                    A[row][col+j] = A[row-n][col+j-n];
                col += 2*n;
            }
            row++;
            if (n > 1)
                schedule(n/2);
        }
    }

    void printA() {
        //print header, then print team schedule
        System.out.printf("%4s", "day");
        System.out.printf("%12s", "teams");
        System.out.println();
        printA(max-1);
    }

    void printA(int n) {
        if (n >= 0) {
            printA(n-1);
            //n=0 is the row to list the teams.  
            //Following rows indicate which team they play on which day
            if (n == 0)
                System.out.printf("%4s", "");
            if (n >= 1)
                System.out.printf("%4s", "D"+n);
            for (int c = 0; c < max; c++)
                System.out.printf("%3d", (A[n][c]));
            System.out.println();
        }
    }
}

public class Hw10 {
    //determine if n is a 2's power
    static boolean isPow(int n) {
        while (n > 1) {
            if (n%2 != 0)
                return false;
            n = n / 2;
        }
        return true;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int teams;

        //prompt user input for teams and print schedule
        do {
            System.out.print("How many teams (0 to exit): ");
            teams = in.nextInt();
            //check to make sure user input is a power of 2.
            do {
                if (isPow(teams) == false) {
                    System.out.println("Invalid input, must be a power of 2.");
                    System.out.print("How many teams (0 to exit): ");
                    teams = in.nextInt();
                }
            } while (isPow(teams) == false);

            //initialize array to avoid out of bounds errors on repeat tries
            MySchedule sched = new MySchedule();

            //initialize first row of array with number of teams
            for (int i = 0; i < teams; i++)
                sched.A[0][i] = i+1;
            sched.max = teams;

            sched.schedule(teams/2);
            sched.printA();
            System.out.println();
        } while (teams > 0);
    }
}