Я пытаюсь написать сортировку выбора с восходящими и нисходящими вариантами - PullRequest
0 голосов
/ 03 мая 2018

У меня есть метод сортировки для сортировки объектов по годовой переменной. У меня все работает, сортировка в порядке возрастания, не получается заставить работать в порядке убывания. Было бы здорово, если бы кто-то мог взглянуть на код и, возможно, указать мне правильное направление

public static void sortYears(ArrayList<Movies3> list, int ad){
    int max, min,  i, j;
    Movies3 temp;

    if(ad == 1){
        for (i = 0; i < list.size() - 1; i++){
            max = i;

            for (j = i + 1; j < list.size(); j++){
                if (list.get(max).getYear() > list.get(j).getYear()){
                    max = j;
                }
            }

            temp = list.get(i);
            list.set(i, list.get(max));
            list.set(max, temp);
        }
    }else if(ad == 2){
        for (i = 0; i < list.size() - 1; i++){
            min = i;

            for (j = i + 1; j > list.size(); j++){
                if (list.get(min).getYear() < list.get(j).getYear()){
                    min = j;
                }
            }

            temp = list.get(i);
            list.set(i, list.get(min));
            list.set(min, temp);
        }
    }
}

Ответы [ 4 ]

0 голосов
/ 03 мая 2018

Я предлагаю вам, чтобы ваш класс Movies3 должен реализовывать интерфейс Comparable и , использовать метод сортировки класса Java List и , создать собственный компаратор . Я думаю, что это лучший и более элегантный способ сделать это.

Это может быть что-то вроде этого:

Для класса Movie3

public class Movie3 implements Comparable<Movie3> {


private int year;
    private String author;
    private String genre;
    public Movie3(int year, String author, String genre) {
        super();
        this.year = year;
        this.author = author;
        this.genre = genre;
    }
    /**
     * @return the year
     */
    public int getYear() {
        return year;
    }
    /**
     * @param year the year to set
     */
    public void setYear(int year) {
        this.year = year;
    }
    /**
     * @return the author
     */
    public String getAuthor() {
        return author;
    }
    /**
     * @param author the author to set
     */
    public void setAuthor(String author) {
        this.author = author;
    }
    /**
     * @return the genre
     */
    public String getGenre() {
        return genre;
    }
    /**
     * @param genre the genre to set
     */
    public void setGenre(String genre) {
        this.genre = genre;
    }

    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("Year: "+this.getYear());
        sb.append("Author: "+this.getAuthor());
        sb.append("Genre: "+this.getGenre());
        return sb.toString();
    }
    public int compareTo(Movie3 m) {
        return Integer.compare(this.year, m.year);
    }

}

С другой стороны, Пользовательский компаратор это просто:

import java.util.Comparator;

public class MovieYearComparator implements Comparator<Movie3> {
    private boolean reverse;

    public MovieYearComparator(boolean reverse) {
        super();
        this.reverse = reverse;
    }

    @Override
    public int compare(Movie3 m1, Movie3 m2) 
    {
        if (reverse)
            return m1.getYear() < m2.getYear() ? 1 : m1.getYear() == m2.getYear() ? 0 : -1;
        else
            return m1.getYear() < m2.getYear() ? -1 : m1.getYear() == m2.getYear() ? 0 : 1;
    }
}

И, наконец, тест:

import java.util.ArrayList;
import java.util.List;

import data.Movie3;
import data.MovieYearComparator;

public class test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<Movie3> movies = new ArrayList<Movie3>();
        movies.add(new Movie3(1000,"sds","sdf"));
        movies.add(new Movie3(1001,"sds","sdf"));
        movies.add(new Movie3(2001,"sds","sdf"));
        movies.add(new Movie3(2444,"sds","sdf"));
        movies.add(new Movie3(1002,"sds","sdf"));
        movies.add(new Movie3(1003,"sds","sdf"));
        System.out.println(movies.toString());
        boolean reverse = true;
        movies.sort(new MovieYearComparator(!reverse));
        System.out.println(movies.toString());
        movies.sort(new MovieYearComparator(reverse));
        System.out.println(movies.toString());  

    }
}
0 голосов
/ 03 мая 2018

Заменить прямые сравнения, такие как list.get(max).getYear() > list.get(j).getYear(), на Компаратор : comparator.compare(list.get(max).getYear(), list.get(j).getYear()) > 0

Вы можете легко добиться перевернутой сортировки с Comparator.reversed ()

0 голосов
/ 03 мая 2018

Ваши имена переменных и области действительно сбивают с толку, много дублированного кода.

for (j = i + 1; j > list.size(); j++) - эта строка кода никогда не будет выполняться в большинстве случаев.

Это исправление для вашего нисходящего порядка:

// the same walk as for ASC but reversed comparison
for (int i = 0; i < list.size() - 1; i++) {
    candidateIndex = i;

    for (int j = i + 1; j < list.size(); j++) {
        if (list.get(candidateIndex).getYear() < list.get(j).getYear()) {
            candidateIndex = j;
        }
    }

    temp = list.get(i);
    list.set(i, list.get(candidateIndex));
    list.set(candidateIndex, temp);
}

Вам определенно нужно взглянуть на Comparator :

Функция сравнения, которая накладывает общее упорядочение на некоторые коллекция предметов. Компараторы могут быть переданы в метод сортировки (например, Collections.sort или Arrays.sort), чтобы обеспечить точное управление по порядку сортировки. Компараторы также могут быть использованы для контроля заказа определенных структур данных (таких как отсортированные наборы или отсортированные карты), или обеспечить порядок для коллекций объектов, которые не имеют естественный порядок. Упорядочение, наложенное компаратором c на набор элементов S, называется быть согласованным с равными тогда и только тогда, когда c.compare (e1, e2) == 0 имеет то же самое логическое значение, что и e1.equals (e2) для каждых e1 и e2 в S.

Я напишу полный пример с использованием компараторов:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class Main {
    /**
     * Defining comparator for ascending order by default
     */
    public static final Comparator<Movies3> COMPARATOR = (m1, m2) -> m1.getYear() - m2.getYear();

    public static void main(String[] args) {
        List<Movies3> movies = new ArrayList<>(
            Arrays.asList(new Movies3(1990), new Movies3(1995), new Movies3(2000)));

        sortYears(movies, true);
        System.out.println(movies);

        sortYears(movies, false);
        System.out.println(movies);
    }

    public static void sortYears(List<Movies3> list, boolean asc) {
        int candidateIndex; // index of candidate whatever min or max
        Movies3 temp;
        Comparator<Movies3> comparator;

        if (asc) {
            comparator = COMPARATOR;
        } else {
            comparator = COMPARATOR.reversed(); // switch to DESC order
        }

        for (int i = 0; i < list.size() - 1; i++) {
            candidateIndex = i;

            for (int j = i + 1; j < list.size(); j++) {
                if (comparator.compare(list.get(candidateIndex), list.get(j)) > 0) {
                    candidateIndex = j;
                }
            }

            temp = list.get(i);
            list.set(i, list.get(candidateIndex));
            list.set(candidateIndex, temp);
        }
    }
}

Выход:

[year 1990, year 1995, year 2000]
[year 2000, year 1995, year 1990]

Вы также можете позволить вашему классу реализовать Comparable , чтобы определить для него естественный порядок и использовать его вместо Comparator.

0 голосов
/ 03 мая 2018

for (j = i + 1; j > list.size(); j++){

Предикат должен быть j < list.size(); вместо >, иначе ваш цикл никогда не будет повторяться как i+1 всегда <=n, поэтому j всегда <=n

...