2016-04-06 4 views
3

У меня есть два массива, один хранит расстояние от городов, а другой хранит соответствующее население. Все работает нормально, если расстояние в городах возрастает. Но пусть говорят, если кто-то вводит расстояние случайным образом. Как я могу отсортировать массив городов, а также убедиться, что население соответствующего города находится в том же индексе, что и индекс его соответствующего городского населения.Сортировка параллельных массивов в Java

Например:

  • Город 1 с населением 333
  • Город 3 имеет население 33333
  • Город 5 с населением 33

int[] city = {1, 3, 5}; 
int[] pop = {333, 33333, 33}; 

Все отлично, потому что работает массив города уже отсортирован.

Но когда я вход:

int[] city = {3, 1, 5}; 
    int[] pop = {3333, 333, 33}; 

Большая проблема!

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

+7

Поскольку они связаны с информацией, возможно, это хорошая идея сохранить обе данные в объекте City. – marcellorvalle

+5

Недавно я видел несколько вопросов, в которых параллельные массивы занимают видное место. Это так 1960-е. Кто учит этому? Зачем? Как мы можем заставить их остановить это и научить принципам OO с первого дня? –

ответ

1

«дешевый» способ будет иметь третий массив, который будет содержать от 0 до п, представляющего индекс других массивов

Но проблемы у вас возникли бы исчезнуть, если они были сгруппированы в классе, как информация кажется логически связанной. Тогда вы бы реализовать Сопоставимыми: https://stackoverflow.com/a/18896422

8

Хороший способ сделать это иметь класс города:

class City{ 
    private int id; 
    private long population; 

    //... getters, setters, etc 
} 

город компаратор класс:

class CityPopulationComparator implements Comparator<City> { 
    @Override 
    public int compare(City c1, City c2) { 
     return Long.compare(c1.getPopulation(), c2.getPopulation()); 
    } 
} 

и список массива городов:

ArrayList<City> cities; 

и, наконец, сортировать его, используя:

Collections.sort(cities, new CityPopulationComparator()); 

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

+1

Класс 'City' может даже реализовать' Comparable 'в качестве альтернативы. Таким образом, вы можете вызвать 'Collections.sort' только с коллекцией' city'. –

+0

Кроме того, при работе с сортировкой и коллекциями ваш объект должен переопределять методы 'equals()' и 'hashCode()'. Это сделает каждый объект поистине уникальным. –

+0

@ Mr.Polywhirl Да. и, поскольку я думал, что это не «естественный» порядок города, я предпочитал путь «Компаратор». –

2

Если ваш город идентификатор уникален:

int[] city = {3, 1, 5}; 
    int[] pop = {3333, 333, 33}; 
    Map<Integer, Integer> arr = new HashMap<Integer, Integer>(city.length); 
    for (int i = 0; i < city.length; i++) { 
     arr.put(city[i], pop[i]); 
    } 
    Arrays.sort(city); 
    for (int i = 0; i < city.length; i++) { 
     pop[i] = arr.get(city[i]); 
    } 
3

Правильное решение this.Однако, если вы хотите полностью безумный хак, вы можете сделать это:

public final class ParallelIntArrays extends AbstractList<int[]> { 

    private final int[] array1; 
    private final int[] array2; 

    public ParallelIntArrays(int[] array1, int[] array2) { 
     if (array1.length != array2.length) 
      throw new IllegalArgumentException(); 
     this.array1 = array1; 
     this.array2 = array2; 
    } 

    @Override 
    public int[] get(int i) { 
     return new int[] { array1[i], array2[i] }; 
    } 

    @Override 
    public int size() { 
     return array1.length; 
    } 

    @Override 
    public int[] set(int i, int[] a) { 
     if (a.length != 2) 
      throw new IllegalArgumentException(); 
     int[] b = get(i); 
     array1[i] = a[0]; 
     array2[i] = a[1]; 
     return b; 
    } 
} 

Тогда вы можете сделать:

int[] city = {5, 1, 2, 4, 3 }; 
int[] pop = {100, 30, 4000, 400, 5000}; 
new ParallelIntArrays(city, pop).sort(Comparator.comparingInt(arr -> arr[0])); 
System.out.println(Arrays.toString(city)); 
System.out.println(Arrays.toString(pop)); 

Обратите внимание, что, как написано выше, ParallelIntArrays не функционирует правильно, как List. Например, list.contains(list.get(0)) даст false. Если вы сделали это List<IntBuffer> или List<List<Integer>>, это будет исправлено.