[英]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.