合并排序。错误--线程中的异常";“主要”;java.lang.ArrayIndexOutofBounds异常:2
大家好!我这里有一个程序,它使用合并排序对一个文件中的50000个单词进行排序。我在托马斯·科曼的算法介绍中遵循了他的伪代码,当我手动“去修饰”它时,它似乎是正确的。但是,当我运行该程序时,线程“main”java.lang.ArrayIndexOutOfBoundsException:2中会显示合并排序。错误--线程中的异常";“主要”;java.lang.ArrayIndexOutofBounds异常:2,java,mergesort,arrays,Java,Mergesort,Arrays,大家好!我这里有一个程序,它使用合并排序对一个文件中的50000个单词进行排序。我在托马斯·科曼的算法介绍中遵循了他的伪代码,当我手动“去修饰”它时,它似乎是正确的。但是,当我运行该程序时,线程“main”java.lang.ArrayIndexOutOfBoundsException:2中会显示异常。是的,我认为这是由于大量的无词(即50000个),但即使我将其减少到10个,仍然显示出相同的错误 import java.io.*; import java.util.*; public cla
异常。是的,我认为这是由于大量的无词(即50000个),但即使我将其减少到10个,仍然显示出相同的错误
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static void merge(String[] A, int p, int q, int r) {
int n1 = q-p+1;
int n2 = r-q;
String[] L = new String[n1+1];
String[] R = new String[n2+1];
for (int i=1; i<n1; i++) {
L[i] = A[p+i-1];
}
for (int j=1; j<n2; j++) {
R[j] = A[q+j];
}
L[n1+1] = "zzzzz"; //for infinity because if I use Math.floor, it will return a double
R[n2+1] = "zzzzz";
int i=1;
int j=1;
for (int k=p; k<=r; k++) {
int comparison = L[i].compareTo(R[j]);
if (comparison <= 0){
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
}
}
public static void mergeSort (String[] A, int p, int r) {
if (p<r) {
int q = (p+r)/2;
mergeSort(A, p, q);
mergeSort(A, q+1, r);
merge(A, p, q, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 50000;
try {
Scanner file = new Scanner(new File(args[0]));
String[] words = new String[NO_OF_WORDS];
int i = 0;
while(file.hasNext() && i < NO_OF_WORDS) {
words[i] = file.next();
i++;
}
long start = System.currentTimeMillis();
mergeSort(words, 0, words.length-1);
long end = System.currentTimeMillis();
System.out.println("Sorted Words: ");
for(int j = 0; j < words.length; j++) {
System.out.println(words[j]);
}
System.out.print("Running time: " + (end - start) + "ms");
}
catch(SecurityException securityException) {
System.err.println("Error");
System.exit(1);
}
catch(FileNotFoundException fileNotFoundException) {
System.err.println("Error");
System.exit(1);
}
}
}
您的merge()
方法有一个大问题:
String[] L = new String[n1+1];
String[] R = new String[n2+1];
不会和你玩得很好
L[n1+1] = "zzzzz"; //for infinity because if I use Math.floor, it will return a double
R[n2+1] = "zzzzz";
无论n1
和n2
的值如何,这里都会出现ArrayIndexOutOfBoundsException
,因为数组在Java中是基于0的。我不知道什么是伪代码,但您的实现似乎是错误的。我看过维基百科的合并排序,它是完全不同的
所以我不会在这里给你完整的工作算法。我将为您提供解决indexOutOfBounds问题的解决方案,但您仍然需要在实现上做更多的工作
在Java中,执行此操作时:
String[] L = new String[5];
您可以声明一个字符串数组,其中可以包含5
个字符串
对这些字符串的访问是这样进行的:L[anIndex]
第一个元素位于索引0
因此,如果您有一个大小为5
的数组,那么最后一个元素位于索引4
(因为我们从0开始)
在代码中执行以下操作:
String[] L = new String[n1+1];
String[] R = new String[n2+1];
然后:
L[n1+1] = "zzzzz";
R[n2+1] = "zzzzz";
所以在这里,您总是试图访问一个索引不存在的字符串。
每个数组中的最后一个元素分别是n1
和n2
(因为数组大小是n1+1
和n2+1
)
我希望通过这个解释,您能够更好地理解数组在Java中的工作原理。现在您必须改进您的实现,因为它仍然不起作用。如果你不太懂的话,可以给我们你用的伪代码
编辑:
好的,我做了一些更正
这是工作算法。我不得不更改几个索引以适应Java“基于0的数组”,请看:
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static void merge(String[] A, int p, int q, int r) {
int n1 = q-p+1;
int n2 = r-q;
if(A[p]==null || A[q]==null)return;
String[] L = new String[n1+1];
String[] R = new String[n2+1];
for (int i=0; i<n1; i++) {
L[i] = A[p+i];
}
for (int j=0; j<n2; j++) {
R[j] = A[q+j +1];
}
L[n1] = "zzzzz"; //for infinity because if I use Math.floor, it will return a double
R[n2] = "zzzzz";
int i=0;
int j=0;
for (int k=p; k<=r; k++) {
int comparison = L[i].compareTo(R[j]);
if (comparison <= 0){
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
}
}
public static void mergeSort (String[] A, int p, int r) {
if (p<r) {
int q = (p+r)/2;
mergeSort(A, p, q);
mergeSort(A, q+1, r);
merge(A, p, q, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 50000;
try {
Scanner file = new Scanner("bla blya blay byla ybla");
ArrayList<String> words = new ArrayList<String>();
while(file.hasNext() && words.size() < NO_OF_WORDS) {
words.add(file.next());
}
String [] wordsArray = new String[words.size()];
words.toArray(wordsArray);
long start = System.currentTimeMillis();
mergeSort(wordsArray, 0, wordsArray.length-1);
long end = System.currentTimeMillis();
System.out.println("Sorted Words: ");
for(int j = 0; j < wordsArray.length; j++) {
System.out.println(wordsArray[j]);
}
System.out.print("Running time: " + (end - start) + "ms");
}
catch(SecurityException securityException) {
System.err.println("Error");
System.exit(1);
}
}
}
import java.io.*;
导入java.util.*;
公共类排序分析{
公共静态无效合并(字符串[]A,int p,int q,int r){
int n1=q-p+1;
int n2=r-q;
如果(A[p]==null | | A[q]==null)返回;
字符串[]L=新字符串[n1+1];
字符串[]R=新字符串[n2+1];
对于(int i=0;i发生错误的行是什么?提示:final static int NO_OF_WORDS=50000;
,int i=-1;而(++i
,int length=WORDS.length;对于(int j=-1;+++j
行,其中L[n1+1]=“zzzzzzz”;,,合并(A,p,q,r);排序(A,p,q);
和合并排序(words,0,words.length-1);
恕我直言@FlavioCysne,我认为问题不在主要方面。实际上,它还执行快速排序和插入排序(工作正常),但我只是删除了这些部分,以免您混淆。:)谢谢!array.sort
这是您的排序算法:)记住java数组是0索引的,array[array.length]=XX
永远不会工作。谢谢,Keppil!我应该如何处理我的无穷大声明呢?我尝试了Math.floor,但我只是在传递参数时遇到问题,因为它返回一个双精度。据我所知,这只是一个标记,让您知道列表已用尽。在这种情况下,null
应该可以工作。谢谢。我将L[…]和R[…]设置为null,但数组索引仍然超出范围。您好,谢谢!我刚刚想到Cormen的伪代码从1开始,而不是0。当我删除+1形式L[n+1]
和R,仍然存在相同的错误。我现在加入了Cormen的合并伪代码。@第一夫人请检查我的解决方案。哇,非常感谢你,alain。janinm!!你不仅帮助我完成了代码,而且还启发了我,因为你给我介绍了新技术。我非常感谢你碰巧发现了我的问题。更强大!@FirstLady you'R欢迎!很高兴我的回答能帮你学到一些东西;)
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static void merge(String[] A, int p, int q, int r) {
int n1 = q-p+1;
int n2 = r-q;
if(A[p]==null || A[q]==null)return;
String[] L = new String[n1+1];
String[] R = new String[n2+1];
for (int i=0; i<n1; i++) {
L[i] = A[p+i];
}
for (int j=0; j<n2; j++) {
R[j] = A[q+j +1];
}
L[n1] = "zzzzz"; //for infinity because if I use Math.floor, it will return a double
R[n2] = "zzzzz";
int i=0;
int j=0;
for (int k=p; k<=r; k++) {
int comparison = L[i].compareTo(R[j]);
if (comparison <= 0){
A[k] = L[i];
i++;
}
else {
A[k] = R[j];
j++;
}
}
}
public static void mergeSort (String[] A, int p, int r) {
if (p<r) {
int q = (p+r)/2;
mergeSort(A, p, q);
mergeSort(A, q+1, r);
merge(A, p, q, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 50000;
try {
Scanner file = new Scanner("bla blya blay byla ybla");
ArrayList<String> words = new ArrayList<String>();
while(file.hasNext() && words.size() < NO_OF_WORDS) {
words.add(file.next());
}
String [] wordsArray = new String[words.size()];
words.toArray(wordsArray);
long start = System.currentTimeMillis();
mergeSort(wordsArray, 0, wordsArray.length-1);
long end = System.currentTimeMillis();
System.out.println("Sorted Words: ");
for(int j = 0; j < wordsArray.length; j++) {
System.out.println(wordsArray[j]);
}
System.out.print("Running time: " + (end - start) + "ms");
}
catch(SecurityException securityException) {
System.err.println("Error");
System.exit(1);
}
}
}