在Java中对字符串数组进行合并排序

在Java中对字符串数组进行合并排序,java,arrays,algorithm,Java,Arrays,Algorithm,我目前正试图在Java中实现一个合并排序算法,该算法基于《算法简介:第三版》中的算法。 作者使用了一种分治算法,也实现了哨兵卡。这些卡的值应该是无穷大,但由于我使用的是字符串数组,所以我假设该值为null。显然情况并非如此,因为当我尝试比较L[I]和R[j]时,我得到了一个空指针异常。这是我的密码: public static void main(String[] args) { Scanner textfile = new Scanner(System.in); System.

我目前正试图在Java中实现一个合并排序算法,该算法基于《算法简介:第三版》中的算法。 作者使用了一种分治算法,也实现了哨兵卡。这些卡的值应该是无穷大,但由于我使用的是字符串数组,所以我假设该值为
null
。显然情况并非如此,因为当我尝试比较L[I]和R[j]时,我得到了一个空指针异常。这是我的密码:

public static void main(String[] args) {
    Scanner textfile = new Scanner(System.in);
    System.out.println("Enter a filename: ");
    String fileName = textfile.nextLine();
    String[] words = readArray(fileName);
    mergeSort(words, 0, words.length - 1);
    for (String word : words) {
        System.out.println(word);
    }

}

public static String[] readArray(String file) {
    int ctr = 0;
    try {
        Scanner s1 = new Scanner(new File(file));
        while (s1.hasNextLine()) {
            ctr = ctr + 1;
            s1.nextLine();
        }
        String[] words = new String[ctr];
        Scanner s2 = new Scanner(new File(file));
        for(int i = 0; i < ctr; i++) {
            words[i] = s2.next();
        }
        return words;
    }
    catch (FileNotFoundException e){
        System.out.println("File not found.");
    }
    return null;
}

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 merge(String[] A, int p, int q, int r) {
    int n1 = q - p + 1;
    int n2 = r - q;

    String[] left = new String[n1 + 1];
    String[] right = new String[n2 + 1];

    for (int i = 0; i < n1; i++) {
        left[i] = A[p + i];
    }

    for (int j = 0; j < n2; j++) {
        left[j] = A[q + j + 1];
    }
    left[n1] = null;
    right[n2] = null;
    for (int i = 0, j = 0, k = p; k < r; k++) {
        if (left[i].compareTo(right[j]) <= 0) { \\Null Pointer Exception
            A[k] = left[i];
            i++;

        } else {
            A[k] = right[j];
            j++;

        }
    }
}
publicstaticvoidmain(字符串[]args){
扫描仪文本文件=新扫描仪(System.in);
System.out.println(“输入文件名:”);
字符串文件名=textfile.nextLine();
String[]words=readArray(文件名);
合并排序(单词,0,单词.length-1);
for(字符串字:字){
System.out.println(word);
}
}
公共静态字符串[]readArray(字符串文件){
int ctr=0;
试一试{
扫描仪s1=新扫描仪(新文件(文件));
while(s1.hasNextLine()){
ctr=ctr+1;
s1.nextLine();
}
字符串[]字=新字符串[ctr];
扫描仪s2=新扫描仪(新文件(文件));
对于(int i=0;iif(left[i].compareTo(right[j])您是无穷大-
String
必须满足以下属性:

s.compareTo(infinityString) == -1
对于任何
s
,如果您想使用。也就是说
infinityString=null
不会产生所需的属性,因为它会生成
NullPointerException
,如果此代码
a.compareTo(b)
无论是
a
还是
b
都是
infinityString
。如果简单地使用足够长的
字符串
,输入中就不存在同样长的
字符串
,这将是一个非常难看的解决办法。但是:

  • 非常丑陋和不安全的黑客
  • 浪费记忆
相反,我建议使用以下两种方法之一:

  • 使用您自己的比较方法,而不是
    String#compareTo
    ,该方法为您想要定义的
    infinityString
    生成属性
    compare(s,infinityString)=-1
  • 使用不带哨兵卡的合并排序实现,并简单地消除对无限元素的需要

“我假设该值为空。显然情况并非如此,因为当我尝试比较L[I]和R[j]时,会出现空指针异常。”等等,你是认真的吗?你声明该值为null,因此它抛出了一个null点异常,我看不出有什么问题。可能的重复实际上没有Java字符串保证比任何其他字符串都大(因此适合作为哨兵)所以你可以测试i==n1和j==n2。@Riley是的,这听起来很愚蠢。我这么说是因为我发现了。当我使用
compare()
时,它会在同一行上给我一个越界异常。对不起,我一整天都在这样做。你是说
compare()吗你链接的类的最后一行的
方法?据我所见,它应该可以工作。当我查看
字符串
类中的
compareTo()
时,它说只要传入null值,它就会抛出
NullPointException