我想根据另一个数组(索引)的排序顺序遍历两个数组(A,B),在这种情况下为10、34、32、21。
String[] A: a, b, c, d
String[] B: e, f, g, h
int[] indexes: 10, 34, 32, 21
在这里为不好的例子道歉。我已经更新了索引数组以消除混乱。
预期的输入和输出
输入是三个数组。我想使用索引数组的排序遍历A,B。即我想找到一种方法来使用顺序(a,d,c,b)迭代A并使用顺序(e,h,g,f)来迭代B
我的方法:
我用一种我认为与另一种方法相同的解决方案解决了这个问题。但是,第二种方法不起作用。如果有人可以解释为什么它不起作用,我将不胜感激,因为我认为这可以使我更好地理解Collections.sort在Java中的工作方式。
List<Integer> indexOrder = new ArrayList<>(indexes.length);
for (int i = 0; i < indexes.length; i++) {
indexOrder.add(i);
}
Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[s]));
受this thread的启发,我创建了一个值(1、2、3 ... indexes.length)的ArrayList(首选AList而不是数组),然后使用带有ref的比较器对其进行排序。索引。 以上代码按预期工作。
但是,如果我将最后一行末尾的 indexs(s)更改为 indexes [indexOrder.indexOf(s)] 。排序将给出错误的结果。如果ArrayList的索引与其值相同,为什么indexOf(s)的结果不同于s。
Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[indexOrder.indexOf(s)]));
答案 0 :(得分:6)
您似乎希望indexOrder.indexOf(s)
始终等于s
(因为您的List
初始化为[0, 1, 2, 3]
,其中s
的索引为{ {1}})。
虽然在原始s
indexOrder
中是正确的,但是当List
开始交换Collections.sort
的元素时,可能不再正确。
为了在排序时不依赖List
的顺序,可以创建该indexOrder
的副本:
List
答案 1 :(得分:3)
由于存储在索引中的最大值不会超过1000,所以我认为这种排序算法(这是计数排序的变体)的实现将是最佳选择。
final String[] A = { "a", "b", "c", "d" };
final String[] B = { "e", "f", "g", "h" };
final int[] indexes = { 10, 34, 32, 21 };
// find out the max value in the array.
// The loop can be skipped with maxIndexValue = 1000; but i would most likely save some memory using the loop.
// Can also be replaced with : IntStream.of(indexes).max().getAsInt(), with such a small set of data it won't hurt performance that bad
int maxIndexValue = 0;
for (int indexValue: indexes) {
if (maxIndexValue < indexValue) {
maxIndexValue = indexValue;
}
}
maxIndexValue += 1;
final String[] indexSortedA = new String[maxIndexValue];
final String[] indexSortedB = new String[maxIndexValue];
System.out.println(maxIndexValue);
// each value of A (and B) will be put at indexes position, it will result in a appropriately sorted arrays but with a lot of whitespace.
for (int i = 0; i < indexes.length; ++i) {
indexSortedA[indexes[i]] = A[i];
indexSortedB[indexes[i]] = B[i];
}
// Create final arrays by filtering empty values
final String[] sortedA = Arrays.stream(indexSortedA).filter(v -> v != null && !"".equals(v)).toArray(String[]::new);
final String[] sortedB = Arrays.stream(indexSortedB).filter(v -> v != null && !"".equals(v)).toArray(String[]::new);
此算法的复杂度将为:O(n)+ O(1000)+ O(2n)。它将比任何Collection.sort()
都要好,但是会花费更多的内存。
答案 2 :(得分:0)
我试图同时运行两个代码,并且在两种情况下都得到相同的结果。
案例1:
public static void main(String[] args) {
String[] A = { "a", "b", "c", "d" };
String[] B = { "e", "f", "g", "h" };
int[] indexes = { 0, 4, 2, 1 };
List<Integer> indexOrder = new ArrayList<>(indexes.length);
for (int i = 0; i < indexes.length; i++) {
indexOrder.add(i);
System.out.println(i);
}
//Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[s]));
Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[indexOrder.indexOf(s)]));
System.out.println(indexOrder.toString());
}
输出: 0 1个 2 3
[0,3,2,1]
情况2:
public static void main(String[] args) {
String[] A = { "a", "b", "c", "d" };
String[] B = { "e", "f", "g", "h" };
int[] indexes = { 0, 4, 2, 1 };
List<Integer> indexOrder = new ArrayList<>(indexes.length);
for (int i = 0; i < indexes.length; i++) {
indexOrder.add(i);
System.out.println(i);
}
Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[s]));
//Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[indexOrder.indexOf(s)]));
System.out.println(indexOrder.toString());
}
输出: 0 1个 2 3
[0,3,2,1]