0

下面的程序使用归并排序来排列文件中的前 10,000 个单词。我遵循了 Thomas Cormen 在他的《算法导论》第二版中的伪代码。

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;
        double infinity = Double.POSITIVE_INFINITY;
        int i, j;
        String[] L = null;
        String[] R = null;
        for (i=1; i<=n1; i++) {
            L[i] = A[(int) (p+i-1)];
        }
        for (j=1; j<=n2; j++) {
            R[j] = A[(int) (q+j)];
        }
        L[n1+1] = infinity; //type mismatch: cant convert from double to string
        R[n2+1] = infinity; //same as above
        i=1;
        j=1;
        for (int k=(int) 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 = (int) Math.floor((p+r)/2); //I typecasted q here so I can still pass the variables
            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 = 10000;
        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 of insertion sort: " + (end - start) + "ms");

        }
        catch(SecurityException securityException) {
            System.err.println("Error");
            System.exit(1);
        }
        catch(FileNotFoundException fileNotFoundException) {
            System.err.println("Error");
            System.exit(1);
        }
    }
} 

控制台中显示错误提示
Exception in thread "main" java.lang.Error: Unresolved compilation problems: Type mismatch: cannot convert from double to String Type mismatch: cannot convert from double to String

at SortingAnalysis.merge ... mergeSort and main </code>


我认为这是因为 Math.floor 方法应该是双精度的,但我确实将它类型转换为 int,因此在传递参数时不会有问题。

另外,我认为将字符串分配给无穷大时存在错误。但我只是在遵循 Cormen 的伪代码。这似乎是正确的,因为我自己手动“调试”了代码。但是,当我将其放入代码中时,它不起作用。我哪里错了?我需要你的帮助,伙计们。我是 Java 新手,我仍在缓冲过程中。非常感谢!

4

2 回答 2

3

我认为这是因为 Math.floor 方法应该是双精度的,但我确实将它类型转换为 int,因此在传递参数时不会有问题。

不,它比那更简单。您正在尝试将双精度值分配给字符串数组。你根本做不到。

我强烈怀疑您应该将整个代码更改为使用double[]而不是String[]. 请注意,即使它正在编译(并且在您真正修复所有编译错误之前,您不应该尝试运行它),您也会因此遇到问题:

String[] L = null;
String[] R = null;
for (i=1; i<=n1; i++) {
    L[i] = A[(int) (p+i-1)];
}

这显然会抛出一个NullPointerException. 您没有初始化数组变量以引用数组对象。你想要这样的东西:

double[] L = new double[n1 + 1];
double[] R = new double[n1 + 1];
for (i=1; i<=n1; i++) {
    L[i] = A[(int) (p+i-1)];
}

以 1 为基础的方式使用数组是很奇怪的,顺便说一句...做类似的事情会更惯用

double[] L = new double[n1];
double[] R = new double[n1];
for (i = 0; i < n1; i++) {
    L[i] = A[p + i];
}

感觉就像你在挣扎,因为你想在这里学习两件事:

  • 合并排序的工作原理
  • Java 的工作原理

我将首先专注于理解 Java 语言——那时您将能够更好地将伪代码转换为真实代码。

于 2012-07-09T09:51:07.820 回答
0

无论如何,铸造到一个(int)会做一个地板。

  L[n1+1] = infinity; //type mismatch: cant convert from double to string

这是一个错误,因为您不能将 aa转换double为 aString即使您用toString()它转换它也不正确,因为您只会得到“NaN”,这不是您的目标的 maixmum 字符串值。

您可以在不添加虚拟“无限”值的情况下对其进行编码,我建议您改为这样做。

于 2012-07-09T09:50:18.707 回答