如何对数组进行排序并跟踪java中的索引

Posted

技术标签:

【中文标题】如何对数组进行排序并跟踪java中的索引【英文标题】:How to sort an array and keep track of the index in java 【发布时间】:2014-06-28 12:48:29 【问题描述】:

我正在尝试对整数数组进行排序(递减),但要跟踪原始索引。

我的意思是,例如,如果我有这个数组:

b[] =  4, 5, 3, 5, 2    

使用 Arrays.sort(b, Collections.reverseOrder()) 后它变成 (我正在使用 Arrays.sort,因为在此示例中 b 的长度仅为 5,但在我的问题中,b 的长度可能是 1

b[] =  5, 5, 4, 3, 2 

但我想以某种方式获得原始索引,我的意思是知道

bOrignalIndex[] =  1, 3, 0, 2, 4 

我不知道我的问题是否清楚,请问一切。 我有这段 C++ 代码,它很有帮助,因为它可以满足我的需求

n=4
m=5
tord[] =  
[0] 0   
[1] 1   
[2] 2   
[3] 3   
ts[] =      
[0] 4   
[1] 5   
[2] 3   
[3] 5   



   tord[MAXT], ts[MAXT];
       bool ord(int a, int b)
        return ts[a] > ts[b];    
    int main(void)
        for(int m, n; scanf("%d %d", &m, &n))
            bool possible = true;
            FOR(i=0;i<m, i++) // for each team
                scanf("%d", ts + i); // read team size
                tord[i] = i;
            
            sort(tord, tord + m, ord)

事情是在这样做之后,tord有一个按索引排序的数组,即:

tord[] =  
[0] 1   
[1] 3   
[2] 0   
[3] 2   

【问题讨论】:

听起来像Burrows-Wheeler Transform。 Duplicate? 还有很多类似的 【参考方案1】:

尝试按值对(value, index) 进行排序:

public class Pair implements Comparable<Pair> 
    public final int index;
    public final int value;

    public Pair(int index, int value) 
        this.index = index;
        this.value = value;
    

    @Override
    public int compareTo(Pair other) 
        //multiplied to -1 as the author need descending sort order
        return -1 * Integer.valueOf(this.value).compareTo(other.value);
    

然后,当你要排序时:

public static void main(String[] args) 
    Pair[] yourArray = new Pair[10];

    //fill the array
    yourArray[0] = new Pair(0, 5); yourArray[1] = new Pair(1, 10); //and so on
    Arrays.sort(yourArray);

现在,您有一个由 value 降序排列的 Pair 对象数组。每个对象还包含index-原始数组中的位置。

P。 S. 我用 Java 编写了示例,因为问题有 java 标签。虽然,C++ 的想法是一样的,只是实现方式有点不同。

【讨论】:

非常感谢您的回答:)。我只是在 Pair 类中实现了另外两个方法来返回值和索引 有没有java8更简单的方法?我需要订购一个 int 数组,但如果值与索引较低的值相同,则首先出现。是的,我需要跟踪原始索引。地图呢? 我想这是一种更简单的方法,通过使用 Map。 programcreek.com/2013/03/java-sort-map-by-value【参考方案2】:

OP 海报的示例涉及对整数数组进行排序。如果任何读者有类似的情况,但有一个非原始类型的数组,下面是一个处理非原始数组的类。该课程采用了一些不同的方法。它不修改原始数组,而是创建一个索引数组并排序并返回它。

public class IndirectSorter<T extends Comparable<T>> 
    public int[] sort(T args[]) 
        Integer origindex[] = new Integer[args.length];
        int retval[] = new int[args.length];
        for (int i=0; i<origindex.length; i++) 
            origindex[i] = new Integer(i);
        
        Arrays.sort(origindex, new IndirectCompareClass<T>(args));
        for (int i=0; i<origindex.length; i++) retval[i] = origindex[i].intValue();
        return retval;
    

    class IndirectCompareClass<T extends Comparable<T>> implements Comparator<Integer> 
        T args[];
        public IndirectCompareClass(T args[])  this.args = args; 
        public int compare( Integer in1, Integer in2 ) 
            return args[in1.intValue()].compareTo(args[in2.intValue()]);
        
        public boolean equals( Integer in1, Integer in2 ) 
            return args[in1.intValue()].equals(args[in2.intValue()]);
        
    

要快速调用它,您可以执行以下操作:

public static void main(String args[] ) 
    int indexes[] = new IndirectSorter<String>().sort(args);
    for (int i : indexes) 
        System.out.printf("original pos: %d %s\n", i, args[i] );
    

编辑:如果您愿意重新实现 Arrays.sort(int[]) 方法,则可以避免创建和使用 Integer 对象。这可能很有吸引力。

【讨论】:

【参考方案3】:

以下答案提供了解决问题中解释的问题的主要步骤,但未提供详细代码。

您可以创建具有两个属性valueindex 的自定义Class。其中value是原始属性值,index是排序前的位置。 为此Class 创建一个ArrayList。 将创建的Class 的新对象添加到所需的valueindex

注意:设置index 值的一种可能方法是遍历Arraylist 并使用循环索引设置index 的值。

使用基于value 属性的特殊ComparableArraylist 进行排序。

现在排序后,您可以通过调用其index 属性来知道任何条目的前一个index

【讨论】:

以上是关于如何对数组进行排序并跟踪java中的索引的主要内容,如果未能解决你的问题,请参考以下文章

对数组进行排序并保留原始索引

重新排序 UITableView 单元格并跟踪索引

如何对数组进行排序并返回配置单元中的索引?

PHP如何跟踪关联数组中的顺序?

Java 中的优先级队列,用于跟踪每个节点的位置

Swift 对数组进行排序并返回索引和元素的数组