矩阵和数组索引超出范围时出错

时间:2014-05-10 20:15:45

标签: java arrays matrix

所以,我需要实现这个代码,它将从java中的矩阵乘法中返回括号的最佳解决方案。我为"("")"的印刷做了一个功能。在主要的我做了矩阵M和S的构造解决(dinamic编程)。 打印完第一个"(":

后,我不断收到此错误
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
    at ProgramacaoDinamica.parenterizacao(ProgramacaoDinamica.java:13)
    at ProgramacaoDinamica.main(ProgramacaoDinamica.java:46)

代码:

public class ProgramacaoDinamica {
    private static int[][] s;

    public static void parenterizacao(int[][] s, int i, int j) {
        if (i == j) {
            System.out.println("M" + i);
        } else {
            System.out.println("(");
            parenterizacao(s, i, s[i][j]);
            parenterizacao(s, s[i][j] + 1, j);
            System.out.println(")");
        }
    }

    public static void main(String[] args) {

        int[] p = {15, 5, 10, 20, 25}; //VETOR P DO ENUNCIADO (alteracoes aqui!!!)

        int n = p.length - 1;


        int[][] m = new int[n][n];
        int[][] s = new int[n - 1][n - 1];

        for (int i = 0; i < n; i++) {
            m[i][i] = 0;
        }

        for (int l = 1; l < n; l++) {
            for (int i = 1; i <= l - n + 1; i++) {
                int j = i + l - 1;
                m[i][j] = 9999;
                for (int k = i; k <= j - 1; k++) {
                    int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
                    if (q < m[i][j]) {
                        m[i][j] = q;
                        s[i][j] = k;
                    }
                }
            }
        }
        parenterizacao(s, 1, n);
    }

}

任何人都可以帮我解决这个问题吗?我开始迷失代码? 我遵循这个半码: java1 java2

2 个答案:

答案 0 :(得分:0)

简短的回答是你正在创建一个3x3数组,然后尝试访问第二行中的第5个元素,这显然不存在。

如代码所示,您将伪代码中的s[1..n-1,2..n]映射到java中的s[0..n-1][0..n-2],例如伪代码说s[1,2]你的java使用s[0][0],但你没有减去对parenterizacao(s,1,n)

的调用中的1和2

你有一些索引混合在一些地方被映射到从零开始而没有在其他地方映射,所以你应该使它一致 - 要么直接使用索引,因为它们在伪代码中,并使数组更大而未使用元素(例如,而不是s[0..2][0..2]具有s[0..3][0..4]),或确保每次访问数组时都映射索引。

下面我修改了您的代码,并保留了伪代码中ijkln的原始值,但已减去每个阵列访问适当地使用1或2:

public static void parenterizacao(int[][] s, int i, int j) {
    if (i == j) {
        System.out.println("M" + i);
    } else {
        System.out.println("(");
        parenterizacao(s, i, s[i-1][j-2]);
        parenterizacao(s, s[i-1][j-2] + 1, j);
        System.out.println(")");
    }
}

    for (int i = 1; i <= n; i++) {
        m[i-1][i-1] = 0;
    }

    for (int l = 2; l <= n; l++) {
        for (int i = 1; i <= n - l + 1; i++) {
            int j = i + l - 1;
            m[i-1][j-1] = 9999;
            for (int k = i; k <= j - 1; k++) {
                int q = m[i-1][k-1] + m[k][j-1] + p[i - 1] * p[k] * p[j];
                if (q < m[i-1][j-1]) {
                    m[i-1][j-1] = q;
                    s[i-1][j-2] = k;
                }
            }
        }
    }
    parenterizacao(s, 1, n);

nl也需要在内循环中切换以匹配伪代码。

答案 1 :(得分:0)

问题是你的嵌套循环。

for (int l = 1; l < n; l++)
    for (int i = 1; i < l - n; i++)

此处,n = 3l的界限已经是3.然后您指定i = 3并尝试通过递增i来达到2。

还有一件事,你应该把return;放在递归函数的某个地方。否则,你将有一个无限循环。