嘿我正在研究一种合并排序方法,它不断获得索引超出范围的错误。我无法弄清楚为什么或在哪里发生这种情况。我已经尝试打印出指数,看看递归是否有问题,但我不认为这是非常直接的。
public ArrayList<String> mergeSort(ArrayList<String> words,int first, int last){
if (first < last){
int mid = (first+ last)/2;
mergeSort(words,first,mid);
mergeSort(words,mid+1,last);
merge(words, first, mid, last);
}
return words;
}
public ArrayList<String> merge(ArrayList<String> words, int first, int mid, int last){
int first1 = first;
int last1 = mid;
int first2 = mid+1;
int last2 = last;
int total = first1;
ArrayList<String> temp = new ArrayList<String>();
while ((first1<=last) && (first2 <= last2)){
if (words.get(first1).compareTo(words.get(first2))<=0){
temp.add(total,words.get(first1));
first1++;
}
else{
temp.add(total,words.get(first2));
first2++;
}
total++;
}
while(first1 <= words.size()){
temp.add(total,words.get(first1));// exception occurs here
first1++;
total++;
}
while (first2 <= last2){
temp.add(total,words.get(first2));
first2++;
total++;
}
for (total = first; total <= last; ++total){
words.set(total,temp.get(total));
}
System.out.println(words);
return words;
}
答案 0 :(得分:0)
你的问题是这样的:
temp.set(total,words.get(first1));
你在没有元素的ArrayList
上执行此操作。当你调用.set()
时,你必须传递一个已经在数组中的元素的索引(即total<temp.size()
)。
我认为您需要两个临时列表,并且您希望使用ArrayList.add()
而不是ArrayList.set()
将左半部分的内容放入第一个,而将右半部分放入第二个。然后你可以将它们合并回原来的ArrayList
(在这里,你真的可以使用words.set()
,因为它已经有了元素,只是顺序错误。)
答案 1 :(得分:0)
您的问题是您在空的临时列表中使用set()
。 set()
替换数组中的元素,但数组为空:没有要替换的元素。
您需要做的是add()
进入临时列表而不是使用set()
。元素将按顺序添加,因此按正确的顺序,您不需要total
变量。
现在,当您替换单词中的元素时,它会有所不同。临时列表将包含从0
到(last - first)
的索引元素,并且您希望将first
到last
中的元素替换为单词。为此,我认为以下循环将起作用:
for (String word : temp) {
words.set(first++, word);
}
注意:因为您事先知道临时的最终大小(即last - first + 1
),所以您应该使用以下方式预先分配:
ArrayList<String> temp = new ArrayList<String>(last - first + 1);