Слияние mergeSort входит в бесконечный цикл? - PullRequest
0 голосов
/ 05 июня 2018

Как часть проекта, над которым я работаю, нам нужно взять объект «Song», список которого находится в ArrayList «songCollection».Мне нужно объединить сортировать файл по названию, рангу, исполнителю или году, но при выполнении код переходит в бесконечный цикл (ошибка StackOverflow), и я не уверен, почему.Что не так с моим кодом: список песен: 1965 55 Гари Льюис и плейбои Все любят клоуна 1963 526 Бен Э. Кинг Как я могу забыть 1979 207 Эшфорд и Симпсон нашли лекарство 1981 96 Энди Гибб Time Is Time 1996 169 ВсегоКогда мальчик встречается с девушкой 1962 384 Линда Скотт Есири 1957 315 ​​Фрэнк Синатра Твоя любовь ко мне 1978 302 Джон Денвер Я хочу жить 1954 304 Стэн Кентон и его оркестр The Creep 1993 199 Expos� Пока я могу мечтать 1989 269 Палата лордовЯ хочу быть любимым 1950 267 Бенни Гудман Sextet О, детка!1948 295 Tex Williams & The Western Caravan Suspicion

Код: // чтобы изменить строку выше в песню, добавьте ее в songCollection

 ArrayList<Song> songCollection = new ArrayList<Song>();
 public SongCollection(String fileName) throws FileNotFoundException {
      Scanner input = new Scanner(new File(fileName));
      while (input.hasNextLine())
      {
         addSong(input.nextLine());

      }
}
//getter method
public ArrayList<Song> getSongCollection() {
    return songCollection;
}
public void addSong(String line) {
    //parse the line read from the song file, create the song, and add it to the collection
    StringTokenizer token = new StringTokenizer(line, "\t");
    String year = token.nextToken();
    int intYear = Integer.parseInt(year);

    String rank = token.nextToken();
    int intRank = Integer.parseInt(rank);

    String artist = token.nextToken();
    String name = token.nextToken();

    Song song = new Song(intYear, intRank, artist, name);
    songCollection.add(song);




}


                 public ArrayList<Song>  mergeSort(ArrayList<Song> all, String filter, String file) throws FileNotFoundException {
     //overarching method, divides the array list into left and right array lists, then divides and sorts, and then finally merges back
     //distinction: use of mergeString vs mergeInt based on the type of filter that the list is being sorted for. 
     ArrayList<Song> left = new ArrayList<Song>();
        ArrayList<Song> right = new ArrayList<Song>();
        int center;

        if (all.size() == 1) {    
            return all;
        } 
        else {
            center = all.size()/2;
            for (int i=center; i<all.size(); i++) {
                    right.add(all.get(i));
            }


            //left  = mergeSort(left,filter, file);
            //right = mergeSort(right, filter, file);

            // Merge the results back together.
            if (filter.equalsIgnoreCase("year") || filter.equalsIgnoreCase("rank"))
                mergeInt(left, right, all, filter);
            if (filter.equalsIgnoreCase("artist") || filter.equalsIgnoreCase("title"))
                mergeString(left,right,all,filter);

        }
        PrintStream out = new PrintStream(new File(file));
        for (int x = 0; x < songCollection.size(); x++) {
            out.println(all.get(x).toString());
        }
        out.close();
        return all;

    }
            private void mergeString(ArrayList<Song> left, ArrayList<Song> right, ArrayList<Song> whole, String filter) {
        //'mergeX' for the string filters
        int leftIndex = 0;
        int rightIndex = 0;
        int wholeIndex = 0;

        //checks whether filter is artist or type 
        if(filter.equalsIgnoreCase("artist")) {
            while (leftIndex < left.size() && rightIndex < right.size()) {
                if ( (left.get(leftIndex).artist.compareTo(right.get(rightIndex).artist)) < 0) {
                    whole.set(wholeIndex, left.get(leftIndex));
                    leftIndex++;
                } else {
                    whole.set(wholeIndex, right.get(rightIndex));
                    rightIndex++;
                }
                wholeIndex++;
            }

            ArrayList<Song> rest;
            int restIndex;
            if (leftIndex >= left.size()) {
                // The left ArrayList has been use up...
                rest = right;
                restIndex = rightIndex;
            } else {
                rest = left;
                restIndex = leftIndex;
            }

            for (int i=restIndex; i<rest.size(); i++) {
                whole.set(wholeIndex, rest.get(i));
                wholeIndex++;
            }
        }
        if(filter.equalsIgnoreCase("title")) {
            while (leftIndex < left.size() && rightIndex < right.size()) {
                if ( (left.get(leftIndex).title.compareTo(right.get(rightIndex).title)) < 0) {
                    whole.set(wholeIndex, left.get(leftIndex));
                    leftIndex++;
                } else {
                    whole.set(wholeIndex, right.get(rightIndex));
                    rightIndex++;
                }
                wholeIndex++;
            }

            ArrayList<Song> rest;
            int restIndex;
            if (leftIndex >= left.size()) {
                rest = right;
                restIndex = rightIndex;
            } else {
                rest = left;
                restIndex = leftIndex;
            }

            for (int i=restIndex; i<rest.size(); i++) {
                whole.set(wholeIndex, rest.get(i));
                wholeIndex++;
            }
        }
    }

    private void mergeInt(ArrayList<Song> left, ArrayList<Song> right, ArrayList<Song> whole, String filter) {
        //same as mergeString, but for int fields
        int leftIndex = 0;
        int rightIndex = 0;
        int wholeIndex = 0;

        if(filter.equalsIgnoreCase("year")) {
            while (leftIndex < left.size() && rightIndex < right.size()) {
                if  (left.get(leftIndex).year < right.get(rightIndex).year) {
                    whole.set(wholeIndex, left.get(leftIndex));
                    leftIndex++;
                } else {
                    whole.set(wholeIndex, right.get(rightIndex));
                    rightIndex++;
                }
                wholeIndex++;
            }

            ArrayList<Song> rest;
            int restIndex;
            if (leftIndex >= left.size()) {
                rest = right;
                restIndex = rightIndex;
            } else {
                rest = left;
                restIndex = leftIndex;
            }

            for (int i=restIndex; i<rest.size(); i++) {
                whole.set(wholeIndex, rest.get(i));
                wholeIndex++;
            }
        }
        if(filter.equalsIgnoreCase("rank")) {
            while (leftIndex < left.size() && rightIndex < right.size()) {
                if  (left.get(leftIndex).rank < (right.get(rightIndex).rank)) {
                    whole.set(wholeIndex, left.get(leftIndex));
                    leftIndex++;
                } else {
                    whole.set(wholeIndex, right.get(rightIndex));
                    rightIndex++;
                }
                wholeIndex++;
            }

            ArrayList<Song> rest;
            int restIndex;
            if (leftIndex >= left.size()) {
                rest = right;
                restIndex = rightIndex;
            } else {
                rest = left;
                restIndex = leftIndex;
            }
            for (int i=restIndex; i<rest.size(); i++) {
                whole.set(wholeIndex, rest.get(i));
                wholeIndex++;
            }
...