Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
合并排序。错误--线程中的异常";“主要”;java.lang.ArrayIndexOutofBounds异常:2_Java_Mergesort_Arrays - Fatal编程技术网

合并排序。错误--线程中的异常";“主要”;java.lang.ArrayIndexOutofBounds异常: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个单词进行排序。我在托马斯·科曼的算法介绍中遵循了他的伪代码,当我手动“去修饰”它时,它似乎是正确的。但是,当我运行该程序时,线程“main”java.lang.ArrayIndexOutOfBoundsException:2中会显示
异常。是的,我认为这是由于大量的
无词(即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);
        }

    }
}