合并排序与从文件中读取数据

时间:2014-05-14 21:06:03

标签: java file sorting bufferedreader mergesort

我的代码出了什么问题?我正在从一个文件中读取数据,该文件每行包含1个数字,并使用合并排序对其进行排序。我收到了以下错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
       at MergeSort.merge(MergeSort.java:67)
       at MergeSort.sort(MergeSort.java:30)
       at MergeSort.main(MergeSort.java:86)

TEXTFILE:

300
40
512
234
100

我的mergeSort实现有什么问题吗?

这是我的代码:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MergeSort
{
    void sort(int[] arr, int low, int high)
    {
        if(high > low)
        {   

        int mid = (low + high)/2;
        sort(arr,low,mid);

        sort(arr,mid+1,high);

        merge(arr, low, mid+1, high);
        }
    }
    void merge(int arr[], int low,int mid, int high)
    {
        int helper[] = new int[arr.length];

        //copy both halves into helper
        for(int i=0;i< arr.length;i++)
        {
            helper[i] = arr[i];
        }

        //compare elements from left & right, initialize variables
        int helperLeft = low;
        int helperRight = high;
        int curr = mid+1;

        //while if left<=mid && mid+1 <=right && if left < right assign lowest elem to original array
        while(helperLeft <= curr && curr <=helperRight)
        {
            if(helperLeft <= curr)
            {
                arr[helperLeft] = helperLeft;
                helperLeft++;
            }
            else
            {
                arr[curr] = curr;
                curr++;
            }
            helperRight++;
        }
        //copy all elements to arr
        int rem = mid-helperLeft;
        for(int i=0;i<rem;i++)
        {
            arr[helperRight+i] = helper[helperLeft+i];
        }
    }

    public static void main(String[] args) throws NumberFormatException, IOException {
        // TODO Auto-generated method stub

        MergeSort pb = new MergeSort();

        InputStream inputStream = new FileInputStream("task.txt");
        @SuppressWarnings("resource")
        BufferedReader R = new BufferedReader(new InputStreamReader(inputStream));
        int arraySize = Integer.parseInt(R.readLine());
        int[] inputArray = new int[arraySize];
        for (int i = 0; i < arraySize; i++) {
            inputArray[i] = Integer.parseInt(R.readLine());
        }

        pb.sort(inputArray, 0, inputArray.length-1);

        for (int j = 0; j < inputArray.length; j++) {
            System.out.println(inputArray[j]);
        }
    }
}

新例外:

Exception in thread "main" java.lang.NumberFormatException: null
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at coursera.MergeSort.main(MergeSort.java:74)

3 个答案:

答案 0 :(得分:2)

试试这个:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MergeSort {    
    public void mergeSort(Integer[] array, int lo, int n) {
        int low = lo;
        int high = n;
        if (low >= high) {
            return;
        }

        int middle = (low + high) / 2;
        mergeSort(array, low, middle);
        mergeSort(array, middle + 1, high);
        int end_low = middle;
        int start_high = middle + 1;
        while ((lo <= end_low) && (start_high <= high)) {
            if (array[low] < array[start_high]) {
                low++;
            } else {
                int Temp = array[start_high];
                for (int k = start_high - 1; k >= low; k--) {
                    array[k + 1] = array[k];
                }
                array[low] = Temp;
                low++;
                end_low++;
                start_high++;
            }
        }
    }

    public static void main(String[] args) throws NumberFormatException, IOException {
        MergeSort pb = new MergeSort();
        try {
            BufferedReader br = new BufferedReader(new FileReader("E:\\task.txt"));
            List<Integer> lines = new ArrayList<Integer>();
            String line;
            while ((line = br.readLine()) != null) {
                lines.add(Integer.parseInt(line));
            }
            br.close();
            Integer[] inputArray = lines.toArray(new Integer[lines.size()]);
            pb.mergeSort(inputArray, 0, inputArray.length - 1);
            for (Integer i : inputArray) {
                System.out.println(i);
            }
        } catch (IOException ie) {
            System.out.print(ie.getMessage());
        }

    }
}

答案 1 :(得分:1)

除了例外,我认为你的merge逻辑不正确。看看你的代码:

 while(helperLeft <= curr && curr <=helperRight)
        {
            if(helperLeft <= curr)
            {
                arr[helperLeft] = helperLeft;
                helperLeft++;
            }
            else
            {
                arr[curr] = curr;
                curr++;
            }
            helperRight++;
        }

此处,helperLefthelperRightcurr都是数组索引。您正在使用索引设置数组元素,例如a[23]=23。这是不正确的。在MergeSort的合并中,我们应该比较左边和右边的元素并进行合并,而不是索引。

我建议为你的mergesort编写一个unittest,以确保它适用于所有情况(包括极端情况),然后在真实代码中调用你的方法。

如果您的MergeSort.sort()是静态的,也可以。

我也实现了merge(),你可以在这里查看:https://github.com/sk1418/jalgorithm/blob/master/src/main/java/com/kent/algorithm/sorting/MergeSort.java#L130

希望它有所帮助。

答案 2 :(得分:0)

我认为问题在于条件

while(helperLeft <= curr && curr <=helperRight)

在此,您永远不会检查helperLeft或helperRight是否超过Array索引。将其修改为folows:

while(helperLeft < arr.length
     && helperRight< arr.length
     &&  helperLeft <= curr 
     && curr <=helperRight)
{
  // do something
}