Сортировка списка на основе значений другого списка - Java - PullRequest
5 голосов
/ 30 января 2011

Один список с именами: (не отсортировано), например, [Пол, фол, метка]

Другой список с целыми числами: например, [5, 2, 6]

Значения во втором списке являются числами, «выбранными» каждым человеком (именем), поэтому у Павла номер 5, номер фола - 2, номер знака - 6.

Я пытаюсь отсортировать список имен на основе значений второго списка в порядке убывания. Я не могу использовать карту, так как мне нужны оба списка в других случаях в моей программе.

С помощью метода сортировки, который я сделал я получаю такой список: [Пол, Марк, фол]

Как видите, он отсортирован не так, как я хотел бы.

Правильное будет: [mark, paul, foul]

Но я не могу найти ошибку в коде.

public ArrayList<String> sortNames(ArrayList<Integer> results){
    String tmp;
    for (int k=0; k<Names.size()-1; k++) {

        boolean isSorted=true;
        for (int i=1; i<Names.size()-k; i++) {

             if (results.get(i)>results.get(i-1)  ) {

                tmp=Names.get(i);
                Names.set(i,Names.get(i-1));
                Names.set(i-1,tmp);

                isSorted=false;
            }
        }
        if (isSorted) break;
    }
    return Names;

}

EDIT !!! с помощью ответов ниже, код:

    public ArrayList<String> sortNames(ArrayList<Integer> results){
        String tmp2;
        int tmp;
        for (int k=0; k<Names.size()-1; k++) {

            boolean isSorted=true;
            for (int i=1; i<Names.size()-k; i++) {

                 if (results.get(i)>results.get(i-1)  ) {
                     tmp=results.get(i);
                     results.set(i,results.get(i-1));
                     results.set(i-1,tmp);


                    tmp2=Names.get(i);
                    Names.set(i,Names.get(i-1));
                    Names.set(i-1,tmp2);

                    isSorted=false;
                }
            }
            if (isSorted) break;
        }
    return Names;

}

Этот код работает правильно (для небольших списков) У меня есть только вопрос, почему он не работает для таких объектов, как ImageIcon. Есть идеи?

Ответы [ 5 ]

6 голосов
/ 30 января 2011

Избавьтесь от двух списков. Если данные связаны, то данные должны храниться вместе в простом классе. Затем весь класс добавляется в список, где вы можете при необходимости отсортировать отдельные свойства. Вы можете использовать Bean Comparator для сортировки этого списка по своему усмотрению.

2 голосов
/ 30 января 2011

Вы сортируете Имена списков на основе значений результатов списка ... и это заканчивается только из-за условия k<Names.size()-1. В пузырьковой сортировке такое условие обычно вообще не требуется, что показывает, что что-то не так.

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

Edit:

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

Конечно, вы можете (при условии, что числа уникальны):

Map<Integer, String> m = new HashMap<Integer, String>();
for (int i=0; i<results.size(); ++i) m.put(results.get(i), Names.get(i));
Collections.sort(results);
for (int i=0; i<results.size(); ++i) Names.set(i, m.get(results.get(i));

Возможны ошибки, но идея должна быть ясной.

Есть еще одно решение, использующее класс пар (результат, имя), который работает даже с неуникальными числами, если вам это нужно.

Немного более короткое решение:

Map<Integer, String> m = new TreeMap<Integer, String>();
for (int i=0; i<results.size(); ++i) m.put(results.get(i), Names.get(i));
Names.clear();
Names.addAll(m.values());

Это основано на свойствах TreeSet.values ​​ " Итератор коллекции возвращает значения в порядке возрастания соответствующих ключей " и List.addAll" Добавляет все элементы из указанной коллекции в конец этого списка в том порядке, в котором они возвращаются итератором указанной коллекции"

1 голос
/ 30 января 2011

Вот вам и самая ужасная быстрая сортировка, которую вы когда-либо получали, самый простой принцип: когда вы меняете 1-й список, меняйте 2-й по ходу.Надеюсь, это не домашняя работа, но даже если это не так ... Короче, скопируйте / вставьте и наслаждайтесь quickSort(list1, list2) - это все, что вам нужно.Списки отсортированы по первому списку естественного порядка, определяемому как Comparable.

private static void swap(List<?> l1, List<?> l2, int i, int j){
    Collections.swap(l1, i, j);
    Collections.swap(l2, i, j);     
}
private static <T extends Comparable<? super T>>  int partition(List<T> comp, List<?> l2, int left, int right){
    int i = left, j = right;
    T pivot = comp.get((left + right) / 2);

    while (i <= j) {
        while (comp.get(i).compareTo(pivot)<0)
            i++;

        while (comp.get(i).compareTo(pivot)>0)
            j--;

        if (i <= j) {
            swap(comp, l2, i++, j--);
        }
    };
    return i;
}
private <T extends Comparable<? super T>>  void quickSort(List<T> comp, List<?> l2, int left, int right) {
    int index = partition(comp, l2, left, right);

    if (left < index - 1)
        quickSort(comp, l2, left, index - 1);

    if (index < right)
        quickSort(comp, l2, index, right);
}

public <T extends Comparable<? super T>>  void quickSort(List<T> comp, List<?> l2) {
    if (comp.size()<l2.size())
        throw new IndexOutOfBoundsException();
    quickSort(comp, l2, 0, comp.size());
}
1 голос
/ 30 января 2011

Создайте временное имя сопоставления-> число, затем отсортируйте имена с помощью специального компаратора, который использует сопоставление:

Map<String, Integer> m = new HashMap<String, Integer>;
for(int i = 0; i < Names.size(); i++)
    m.put(Names.get(i), results.get(i));
Collections.sort(Names, new Comparator<String>() {
    @Override
    public int compare(String s1, s2) { return m.get(s2) - m.get(s1); }
});

Это решение будет работать, даже если некоторые числа равны.

1 голос
/ 30 января 2011
  1. Создайте список пар (имя, значение), взяв элементы из двух списков попарно (имея класс, который хранит два значения в виде полей). Реализация Comparable для сравнения поля значения.

  2. Сортировать результат с помощью Collections.sort().

  3. Извлечение имен из отсортированного списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...