简体   繁体   English

排序两个并行 arrays

[英]Sorting two parallel arrays

I have two arrays, one stores the distance of the cities and the other stores the corresponding population.我有两个arrays,一个存储城市的距离,另一个存储相应的人口。 Everything works fine if the distance of the cities is in ascending order.如果城市的距离按升序排列,一切正常。 But let say if someone inputs the distance randomly.但是假设有人随机输入距离。 How can I sort the cities array and also make sure that the population of the respective city is in the same index as the index of its respective city population.如何对城市数组进行排序,并确保各个城市的人口与其各自城市人口的索引处于同一索引中。

For example:例如:

  • City 1 has population 333城市 1 有人口 333
  • City 3 has population 33333城市 3 有人口 33333
  • City 5 has population 33城市 5 有人口 33
int[] city = {1, 3, 5};
int[] pop  = {333, 33333, 33};

Everything works fine because the city array is sorted already.一切正常,因为城市数组已经排序。

But when I input:但是当我输入:

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

Big problem!大问题!

I want sort the array city and make sure that the population array has all its elements at the same index as their respective city.我想对数组 city 进行排序,并确保 population 数组的所有元素与其各自城市的索引相同。

The good way of doing this is having a city class:这样做的好方法是有一个城市类:

class City{
    private int id;
    private long population;

    //... getters, setters, etc
}

a city comparator class:城市比较器类:

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

And an array list of cities:以及城市的数组列表:

ArrayList<City> cities;

and finally sort it using:最后使用以下方法对其进行排序:

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

But if you need to have your cities and populations this way, you can write a sort method yourself (a bubble sort for example) and whenever you swap two cities, also swap corresponding pupulations.但是,如果您需要以这种方式拥有您的城市和人口,您可以自己编写一个排序方法(例如冒泡排序),并且每当您交换两个城市时,也交换相应的人口。

The correct solution is this .正确的解决方案是这样的 However if you want a completely mad hack, you can do 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;
    }
}

Then you can do:然后你可以这样做:

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));

Note that as written above, ParallelIntArrays does not function correctly as a List .请注意,如上所述, ParallelIntArrays不能作为List正常运行。 For example list.contains(list.get(0)) would give false .例如list.contains(list.get(0))会给出false If you made it a List<IntBuffer> or a List<List<Integer>> instead, it would be fixed.如果您将其List<IntBuffer>List<List<Integer>> ,它将被修复。

If your city id is unique:如果您的城市 ID 是唯一的:

int[] city = { 3,    1,   5};
int[] pop  = {3333, 333, 33};
Map<Integer, Integer> arr = new HashMap<>(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]);
}

The same using SortedMap同样使用SortedMap

int[] city = { 3,    1,   5};
int[] pop  = {3333, 333, 33};
SortedMap<Integer, Integer> arr = new TreeMap<>();
for (int i = 0; i < city.length; i++) {
    arr.put(city[i], pop[i]);
}
System.out.println(arr.keySet());
System.out.println(arr.values());

A "cheap" way would be to have a third array which would contain 0 to n representing the index of the other arrays “便宜”的方法是使用第三个数组,其中包含 0 到 n 表示其他数组的索引

But the problem you are having would disappear if they were grouped in a class, both information seem logically related.但是,如果将它们分组在一个类中,您遇到的问题就会消失,这两种信息在逻辑上似乎是相关的。 Then you would implement Comparable: https://stackoverflow.com/a/18896422然后你将实现 Comparable: https : //stackoverflow.com/a/18896422

public static void main(String[] args) {
    Integer[] bidAmount = {3000, 54000, 2000, 1000, 5600};
    String[] bidderName = {"Jenny", "Mike", "Alvin", "Berry", "John"};
    Map<Integer, String> stringTreeMap = new TreeMap<>();
    stringTreeMap.put(bidAmount[0], bidderName[0]);
    stringTreeMap.put(bidAmount[1], bidderName[1]);
    stringTreeMap.put(bidAmount[2], bidderName[2]);
    stringTreeMap.put(bidAmount[3], bidderName[3]);
    stringTreeMap.put(bidAmount[4], bidderName[4]);

    for (Map.Entry<Integer, String> entry : stringTreeMap.entrySet()) {
        Integer key = entry.getKey();
        String value = entry.getValue();

        System.out.println(key + " => " + value);
    }
}

You can collect a third array containing pairs of elements of these two arrays and sort it.您可以收集包含这两个数组的元素对的第三个数组并对其进行排序。 Then you can iterate over this array and replace the elements of the first two arrays:然后你可以迭代这个数组并替换前两个数组的元素:

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

int[][] sorted = IntStream.range(0, city.length)
        // Stream<int[]>
        .mapToObj(i -> new int[]{city[i], pop[i]})
        // sort by city
        .sorted(Comparator.comparing(arr -> arr[0]))
        .toArray(int[][]::new);

// replace the elements of the first two arrays
IntStream.range(0, sorted.length).forEach(i -> {
    city[i] = sorted[i][0];
    pop[i] = sorted[i][1];
});

System.out.println(Arrays.toString(city)); // [1, 3, 5]
System.out.println(Arrays.toString(pop)); // [33333, 333, 33]

See also: How do I sort two arrays in relation to each other?另请参阅:如何对两个数组进行相互排序?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM