[英]Sorting two parallel arrays
我有兩個arrays,一個存儲城市的距離,另一個存儲相應的人口。 如果城市的距離按升序排列,一切正常。 但是假設有人隨機輸入距離。 如何對城市數組進行排序,並確保各個城市的人口與其各自城市人口的索引處於同一索引中。
例如:
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.