【问题标题】:Sort ArrayList using predefined list of indices使用预定义的索引列表对 ArrayList 进行排序
【发布时间】:2016-02-21 12:32:28
【问题描述】:

我正在尝试使用预定义的索引数组对 ArrayList 进行排序。 我当前的示例使用原始 ArrayList 的副本进行排序,因此对于较大对象的 ArrayList 不可扩展

package sortExample;

import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;

public class sortExample {

    public static void main(String[] args) {

        String [] str = new String[] {"a","b","c","d"};
        ArrayList<String> arr1 = new ArrayList<String>(Arrays.asList(str));

        int [] indices = {3,1,2,0};

        ArrayList<String> arr2 = new ArrayList(arr1.size());

        for (int i = 0; i < arr1.size(); i++) {
          arr2.add("0");
        }

        int arrIndex = 0;
        for (int i : indices){
            String st = arr1.get(arrIndex);
            arr2.set(i, st); 
            arrIndex++;
        }

      System.out.println(arr1.toString());
      System.out.println(arr2.toString());
    }

}

【问题讨论】:

  • 你有什么问题?你怎么做有点复杂,但它有效......
  • 是否可以在不创建副本 arr2 的情况下使用索引数组对 ArrayList arr1 进行排序?
  • 为什么你不只使用 Collections.sort()?
  • 第二个列表你不用担心!它只会保存对已经存在的对象的引用,因此它的大小与对象的大小无关!
  • @VDanyliuk 在这种情况下,要使用 Collections.sort(),必须在要排序的对象中包含索引列表。

标签: java sorting arraylist


【解决方案1】:

要重用相同的数据,请参阅我的解决方案:

public static void main(String[] args) {

    String[] strs = new String[]{"a", "b", "c", "d"};
    int[] indices = {3, 1, 2, 0};

    String tmp;
    for (int i = 0; i < strs.length; i++) {
        if (i != indices[i]) {
            tmp = strs[i];
            strs[i] = strs[indices[i]];
            strs[indices[i]] = tmp;

            indices[indices[i]] = indices[i];
            indices[i] = i;
        }
    }

    for (int i : indices) {
        System.out.print(i + " ");
    }
    System.out.println();
    for (String str : strs) {
        System.out.print(str + " ");
    }
}

输出是:

0 1 2 3
d b c a

【讨论】:

  • @scs - 根据索引数组重新排序数组将比根据索引数组复制到另一个数组更复杂。就地重新排序的时间复杂度为 O(n),因为每次交换都至少放置一个元素。有一些更快的变化可以置换循环,旋转原始数组的子集(或全部)。对于 2 个循环,它仍然是一个交换,对于 3 个或更多循环,如果它们存在,那么旋转方法会快一点,temp = 1st element, 1st element = 2nd element, 2nd element = 3rd element, ... , 第 n 个元素 = 温度。
  • @rcgldr 我必须承认我没有深入研究重新排序算法 - O(n) 复杂度足以满足我的需求。
  • @hsnkhrmn:我现在看到上面的答案使用了切换并且比我的示例更优雅。我对您的解决方案投了赞成票。在我的问题中,我正在考虑一个我可能忽略了解决方案是单线的 java 函数。
  • @rcgldr 最多只有 n/2 次切换操作。如前所述,这里的复杂性是 O(n)。当排序开始起作用(通过比较器)时,最多为 O(nlogn)。如果您寻找一个线性代码, TreeMap 似乎是一种解决方案。通过值和值的实际索引添加到 TreeMap,完成后获取树的值。值将按键排序。
【解决方案2】:

根据周期交替重新排序。请注意,索引将更改为 {0,1,2,3}。我还没有安装 Java,所以我将工作 C++ 代码转换为我认为正确的 Java 语法。

    for (int i = 0; i < arr1.size(); i++) {
        if(i != indices[i]) {
            String st = arr1.get(i);
            int t = indices[i];
            int k = i;
            int j;
            while(i != (j = indices[k])){
                arr1.set(k, arr1.get(j));
                indices[k] = k;
                k = j;
            }
            arr1.set(k, st);
            indices[k] = k;
        }
    }

对于这种特定情况 {3,1,2,0},所有这一切都是交换 0 和 3。最长的循环发生在索引旋转时,例如 {3 0 1 2},在这种情况下 st= arr1[0], arr1[0] = arr1[3], arr[3] = arr1[2], arr1[2] = arr1[1], arr1[1] = st.

【讨论】:

    【解决方案3】:

    有一个(一点点)更简单的解决方案:

    int [] indices = {3,1,2,0};
    ArrayList<String> arr2 = new ArrayList<String>();
    
    for (int i = 0; i < arr1.size(); i++) {
        arr2.add(arr1.get(indices[i]));
    }
    

    【讨论】:

      【解决方案4】:

      在下面,只需对新数组使用“索引”即可。

      public class Sorting {
          public static void main(String[] args) {
               String [] str = new String[] {"a","b","c","d"};
      
                  int [] indices = {3,1,2,0};
      
                  String sorted [] = new String [str.length] ;
                  int i = 0;
                  for (String string : str) {
                      sorted[indices[i]] = string;
                      i++;
                  }
      
                  for (String string : sorted) {
                      System.out.print(string + " ");
                  }
          }
      }
      

      打印:d b c a

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-25
        • 2012-09-07
        • 1970-01-01
        • 2013-11-29
        • 2010-12-21
        • 2012-11-27
        • 1970-01-01
        相关资源
        最近更新 更多