簡體   English   中英

排序兩個並行 arrays

[英]Sorting two parallel arrays

我有兩個arrays,一個存儲城市的距離,另一個存儲相應的人口。 如果城市的距離按升序排列,一切正常。 但是假設有人隨機輸入距離。 如何對城市數組進行排序,並確保各個城市的人口與其各自城市人口的索引處於同一索引中。

例如:

  • 城市 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};

大問題!

我想對數組 city 進行排序,並確保 population 數組的所有元素與其各自城市的索引相同。

這樣做的好方法是有一個城市類:

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

但是,如果您需要以這種方式擁有您的城市和人口,您可以自己編寫一個排序方法(例如冒泡排序),並且每當您交換兩個城市時,也交換相應的人口。

正確的解決方案是這樣的 但是,如果你想要一個完全瘋狂的黑客,你可以這樣做:

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>> ,它將被修復。

如果您的城市 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]);
}

同樣使用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());

“便宜”的方法是使用第三個數組,其中包含 0 到 n 表示其他數組的索引

但是,如果將它們分組在一個類中,您遇到的問題就會消失,這兩種信息在邏輯上似乎是相關的。 然后你將實現 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);
    }
}

您可以收集包含這兩個數組的元素對的第三個數組並對其進行排序。 然后你可以迭代這個數組並替換前兩個數組的元素:

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]

另請參閱:如何對兩個數組進行相互排序?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM