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