尝试复制矩阵时出现ArrayIndexOutOfBoundsException

时间:2019-01-30 14:57:30

标签: java arrays algorithm

我正在制作一个根据字典检查单词的程序,该程序根据字典中的单词检查单词中的每个字母。 我想通过将每个差异保存在矩阵中来对其进行优化,然后在单词具有相同字符的情况下将其复制给下一个单词,因此该程序无需重新计算所有内容。但是,使用我当前的解决方案,我得到了ArrayIndexOutOfBoundsException,但看不到问题所在。

import java.util.LinkedList;
import java.util.List;
import java.util.Arrays;

public class ClosestWords {
    LinkedList<String> closestWords = null;

    static int [][] SaveVal;
    int closestDistance = -1;
    static String savedWord;
    static String savedWrongWord;

    int partDist(String w1, String w2, int w1len, int w2len, int [][] SaveVal) {

        if (w1len == 0) {
            //return w2len;
            //SaveVal[0][w2len] = w2len;
            return w2len;
        }
        else if (w2len == 0) {
            //return w1len;
            //SaveVal[w1len][0] = w1len;
            return w1len;
        }
        else if(SaveVal[w1len-1][w2len-1] != 0) {
            return SaveVal[w1len-1][w2len-1];
        }

        int res = partDist(w1, w2, w1len - 1, w2len - 1, SaveVal) +
                (w1.charAt(w1len - 1) == w2.charAt(w2len - 1) ? 0 : 1);
        int addLetter = partDist(w1, w2, w1len - 1, w2len, SaveVal) + 1;
        if (addLetter < res)
            res = addLetter;
        int deleteLetter = partDist(w1, w2, w1len, w2len - 1, SaveVal) + 1;
        if (deleteLetter < res)
            res = deleteLetter;
        SaveVal[w1len-1][w2len-1] = res;
        return res;
    }

    int Distance(String w1, String w2) {
        int simLetters = checkSim(w1, w2);
        //System.out.println(simLetters);
        if(simLetters > 0)  {
            //Reuse the old array used before
            int [][] tempVal = new int [w1.length()][w2.length()]; // w2.length()
            for(int i = 0; i < SaveVal.length; i++)  {

                for(int j=0; j < SaveVal[i].length; j++)  {
    ############### ERRROR HERE WHEN RUNNING PROGRAM ############
                    tempVal[i][j] = SaveVal[i][j];
                }
            }



            SaveVal = tempVal;
            return (partDist(w1, w2, w1.length(), w2.length(), SaveVal));
        } else {
            //Completly new word
            SaveVal = new int [w1.length()][w2.length()];
            return (partDist(w1, w2, w1.length(), w2.length(), SaveVal));
        }
    }
        /*SaveVal = new int [w1.length()][w2.length()];
        return (partDist(w1, w2, w1.length(), w2.length(), SaveVal));*/

    int checkSim(String w1, String w2)  {
        int counter = 0;
        if(savedWord == null || !savedWrongWord.equals(w1))  {
            return 0;
        }
        char[] char1 = savedWord.toCharArray();
        char[] char2 = w2.toCharArray();
        if(char1.length > char2.length) {
            for(int x = 0; x < char2.length; x++)  {
                if(char1[x] == char2[x])  {
                    counter++;
                }
            }
        }else {
            for(int x = 0; x < char1.length; x++)  {
                if(char1[x] == char2[x])  {
                    counter++;
                }
            }
        }
        return counter;
    }

    public ClosestWords(String w, List<String> wordList) {
        savedWrongWord = w;
        for (String s : wordList) {
            int dist = Distance(w, s);
            savedWord = s;
            if (dist < closestDistance || closestDistance == -1) {
                closestDistance = dist;
                closestWords = new LinkedList<String>();
                closestWords.add(s);
            }
            else if (dist == closestDistance)
                closestWords.add(s);
        }
    }

    int getMinDistance() {
        return closestDistance;
    }

    List<String> getClosestWords() {
        return closestWords;
    }
}

1 个答案:

答案 0 :(得分:0)

您遇到了异常,因为SaveVal和tmpVal没有使用相同的w2。 在我的测试案例中:

        String w = "sa";
        List<String> arrays = new LinkedList<>();
        arrays.add("sdasfq");
        arrays.add("sad");
        ClosestWords words = new ClosestWords(w, arrays);
        System.out.println(words.getClosestWords());

SaveVal是通过使用w1 =“ sa”和w2 =“ sdasfg”创建的。但是,当w2 =“ sad”时,不再创建SaveVal。因此SaveVal是int [2] [7],而tmpVal是int [2] [3]。

您只需使用SaveVal来加速partDist方法的执行。每次迭代wordList时,都应该创建SaveVal。我认为您无法重用不同w2之间的中间结果,例如“ sdasfg”,“ sad”。

因此,您只需删除字段SaveVal,并在Distance()方法中将其声明为局部变量

    int Distance(String w1, String w2) {
        int SaveVal[][] = new int[w1.length()][w2.length()];
        return (partDist(w1, w2, w1.length(), w2.length(), SaveVal));
}

我不明白方法checkSim()。我认为这是多余的。 代码是:

import java.util.LinkedList;
import java.util.List;
import java.util.Arrays;

public class ClosestWords {
    LinkedList<String> closestWords = null;

//    int [][] SaveVal;
    int closestDistance = -1;
    static String savedWord;
    static String savedWrongWord;

    int partDist(String w1, String w2, int w1len, int w2len, int [][] SaveVal) {

        if (w1len == 0) {
            //return w2len;
            //SaveVal[0][w2len] = w2len;
            return w2len;
        }
        else if (w2len == 0) {
            //return w1len;
            //SaveVal[w1len][0] = w1len;
            return w1len;
        }
        else if(SaveVal[w1len-1][w2len-1] != 0) {
            return SaveVal[w1len-1][w2len-1];
        }

        int res = partDist(w1, w2, w1len - 1, w2len - 1, SaveVal) +
                (w1.charAt(w1len - 1) == w2.charAt(w2len - 1) ? 0 : 1);
        int addLetter = partDist(w1, w2, w1len - 1, w2len, SaveVal) + 1;
        if (addLetter < res)
            res = addLetter;
        int deleteLetter = partDist(w1, w2, w1len, w2len - 1, SaveVal) + 1;
        if (deleteLetter < res)
            res = deleteLetter;
        SaveVal[w1len-1][w2len-1] = res;
        return res;
    }

    int Distance(String w1, String w2) {
        int SaveVal[][] = new int[w1.length()][w2.length()];
        return (partDist(w1, w2, w1.length(), w2.length(), SaveVal));
    }


    public ClosestWords(String w, List<String> wordList) {
        savedWrongWord = w;
        for (String s : wordList) {
            int dist = Distance(w, s);
            savedWord = s;
            if (dist < closestDistance || closestDistance == -1) {
                closestDistance = dist;
                closestWords = new LinkedList<String>();
                closestWords.add(s);
            }
            else if (dist == closestDistance)
                closestWords.add(s);
        }
    }

    int getMinDistance() {
        return closestDistance;
    }

    List<String> getClosestWords() {
        return closestWords;
    }

    public static void main(String[] args) {
        String w = "sa";
        List<String> arrays = new LinkedList<>();
        arrays.add("sdasfq");
        arrays.add("sad");
        ClosestWords words = new ClosestWords(w, arrays);
        System.out.println(words.getClosestWords());
    }

}