Java中与索引相关的排序问题
这就是我在寻找解决方案时面临的问题 问题: 我有一个ArrayList,里面有数据20,10,30,50,40,10 如果我们按升序排序,结果将是10,10,20,30,40,50 但我需要的结果是3,1,4,6,5,2。排序后每个元素的索引 严格来说,即使列表中有重复的元素,这也应该有效Java中与索引相关的排序问题,java,sorting,indexing,Java,Sorting,Indexing,这就是我在寻找解决方案时面临的问题 问题: 我有一个ArrayList,里面有数据20,10,30,50,40,10 如果我们按升序排序,结果将是10,10,20,30,40,50 但我需要的结果是3,1,4,6,5,2。排序后每个元素的索引 严格来说,即使列表中有重复的元素,这也应该有效 请分享您解决此问题的想法/方法。我的想法是在aray的每个数据中,在您的值旁边再创建一个属性调用索引。它会保存你的旧索引,然后你可以把它拿出来使用 下面是向每个元素添加索引的方法,用Scala编写。这种方法最
请分享您解决此问题的想法/方法。我的想法是在aray的每个数据中,在您的值旁边再创建一个属性调用索引。它会保存你的旧索引,然后你可以把它拿出来使用 下面是向每个元素添加索引的方法,用Scala编写。这种方法最有意义
list.zipWithIndex.sortBy{ case (elem, index) => elem }
.map{ case (elem, index) => index }
在Java中,您需要创建一个实现comperable的新对象
class IndexedItem implements Comparable<IndexedItem> {
int index;
int item;
public int compareTo(IndexItem other) {
return this.item - other.item;
}
}
这将是非常缓慢的所有indexOf扫描,但如果您只需要做几次,就可以完成工作。根据Hury所说的,我认为最简单的方法是创建一个新的数据类型,看起来像:
public class Foo {
private Integer value;
private int origPosition;
private int sortedPosition;
/*Constructors, getters, setters, etc... */
}
还有一些psuedo代码来说明如何处理它
private void printSortIndexes(ArrayList<Integer> integerList) {
// Create an ArrayList<Foo> from integerList - O(n)
// Iterate over the list setting the origPosition on each item - O(n)
// Sort the list based on value
// Iterate over the list setting the sortedPosition on each item - O(n)
// Resort the list based on origPositon
// Iterate over the lsit and print the sortedPositon - O(n)
}
这不需要很长时间就能实现,但效率极低。您在操作中额外添加了4个On,每次您从列表中添加或删除任何内容时,对象中存储的所有位置都将无效-因此您必须重新计算所有内容。它还要求您对列表进行两次排序
因此,如果这是一个小数据集的一次性小问题,它会起作用,但是如果你想让某个东西长期使用,你可能会想一个更优雅的方法来做;然后在原始列表上循环,找到排序列表中元素的索引,并将其插入到另一个列表中 所以一种方法
public List<Integer> giveSortIndexes(List<Integer> origList) {
List<Integer> retValue = new ArrayList<Integer>();
List<Integer> originalList = new ArrayList<Integer>(origList);
Collections.sort(origList);
Map<Integer, Integer> duplicates = new HashMap<Integer, Integer>();
for (Integer i : originalList) {
if(!duplicates.containsKey(i)) {
retValue.add(origList.indexOf(i) + 1);
duplicates.put(i, 1);
} else {
Integer currCount = duplicates.get(i);
retValue.add(origList.indexOf(i) + 1 + currCount);
duplicates.put(i, currCount + 1);
}
}
return retValue;
}
我还没有测试代码,可能需要对重复代码进行更多的处理。这是我的解决方案。我们定义了一个比较器,根据列表中相应的对象对索引列表进行排序。这给了我们一个索引列表,它实际上是一个映射:索引[i]=x意味着原始列表中位置x处的元素位于排序列表中的元素i处。然后,我们可以很容易地创建反向映射 输出是从0开始的索引:[2,0,3,5,4,1]
那么你关心相等元素的顺序吗?或者你还想告诉我们关于那个特殊的排序顺序?元素的类型是什么?你试过了吗?元素是整数类型的。我需要排序后所有元素的新索引。我不需要排序列表,因此我认为Collections.sort不起作用。你能详细说明一下吗。我需要列表中元素的新索引,正如我在问题中所解释的,我认为这不会像前面所说的那样有效。海报要你按元素排序,而不是按索引,所以你的比较器应该比较项目而不是索引。是的,我不敢相信我做了两次。。。在我的帖子中修正了这个问题。选民应该总是留下评论,不管怎样,我已经把这个标记为一个简单化的例子。现在我被否决了,我在eclipse上检查了它,更新了我的示例,它似乎起了作用。仍然不是最好的,但足以给出一个想法。
public List<Integer> giveSortIndexes(List<Integer> origList) {
List<Integer> retValue = new ArrayList<Integer>();
List<Integer> originalList = new ArrayList<Integer>(origList);
Collections.sort(origList);
Map<Integer, Integer> duplicates = new HashMap<Integer, Integer>();
for (Integer i : originalList) {
if(!duplicates.containsKey(i)) {
retValue.add(origList.indexOf(i) + 1);
duplicates.put(i, 1);
} else {
Integer currCount = duplicates.get(i);
retValue.add(origList.indexOf(i) + 1 + currCount);
duplicates.put(i, currCount + 1);
}
}
return retValue;
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class LookupComparator<T extends Comparable<T>> implements Comparator<Integer> {
private ArrayList<T> _table;
public LookupComparator(ArrayList<T> table) {
_table = table;
}
public int compare(Integer o1, Integer o2) {
return _table.get(o1).compareTo(_table.get(o2));
}
}
public class Test {
public static <T extends Comparable<T>> ArrayList<Integer> indicesIfSorted(ArrayList<T> list) {
ArrayList<Integer> indices = new ArrayList<Integer>();
for (int i = 0; i < list.size(); i++)
indices.add(i);
Collections.sort(indices, new LookupComparator(list));
ArrayList<Integer> finalResult = new ArrayList<Integer>();
for (int i = 0; i < list.size(); i++)
finalResult.add(0);
for (int i = 0; i < list.size(); i++)
finalResult.set(indices.get(i), i);
return finalResult;
}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(20);
list.add(10);
list.add(30);
list.add(50);
list.add(40);
list.add(10);
ArrayList<Integer> indices = indicesIfSorted(list);
System.out.println(indices);
}
}