【问题标题】:Initial indexes of sorted elements of ArrayListArrayList 的已排序元素的初始索引
【发布时间】:2013-03-25 06:35:01
【问题描述】:

下面的代码实现了nfit的升序排序。

public static void main(String[] args) {
    ArrayList<Double> nfit = new ArrayList<Double>();

    nfit.add(2.0);
    nfit.add(5.0);
    nfit.add(1.0);
    nfit.add(8.0);
    nfit.add(3.0);

    // Sort individuals in ascending order
    Collections.sort(nfit);

    System.out.print(nfit);

}

输出是:

[1.0, 2.0, 3.0, 5.0, 8.0]

我的问题是如何获取已排序元素的初始索引?在这个例子中,我的问题的答案如下:

[2, 0, 4, 1, 3]

如何获取这些索引?

【问题讨论】:

    标签: java sorting collections arraylist


    【解决方案1】:

    制作ArrayList 的副本,然后对副本进行排序。之后使用indexOf 方法传递排序数组的元素并调用原始ArrayList

    【讨论】:

      【解决方案2】:

      如果值是唯一的,您可以使用Map&lt;Double, Integer&gt; 来保存值和初始顺序。只需要对map的key进行排序,得到每个key对应的值即可。

      【讨论】:

        【解决方案3】:

        两种解决方案: 1)如果您与 ArrayList 结合,则需要使用 Iterator 来构建解决方案集的索引列表。 2) 切换到带有值和顺序的Map(可以通过排序改变)。

        【讨论】:

          【解决方案4】:

          复制 ArrayList 并排序,然后使用 indexOf。

          ArrayList<Double> nfit = new ArrayList<Double>();
          nfit.add(2.0);
          nfit.add(5.0);
          nfit.add(1.0);
          nfit.add(8.0);
          nfit.add(3.0);
          ArrayList<Double> nstore = new ArrayList<Double>(nfit); // may need to be new ArrayList(nfit)
          Collections.sort(nfit);
          int[] indexes = new int[nfit.size()];
          for (int n = 0; n < nfit.size(); n++){
              indexes[n] = nstore.indexOf(nfit.get(n));
          }
          System.out.println(Arrays.toString(indexes));
          

          如果你想要 ArrayList 中的索引,

          Collections.sort(nstore);
          for (int n = 0; n < nfit.size(); n++){
              nstore.add(n, nfit.indexOf(nstore.remove(n)));
          }
          Collections.sort(nfit);
          

          这将产生一个排序的 ArrayList nfit 和一个 ArrayList 的索引 nstore。

          编辑:在for循环中

          for (int n = 0; n < nfit.size(); nfit++){
              nstore.add(n, nfit.indexOf(nstore.remove(n)));
          }
          

          循环计数必须在 n 上迭代,而不是在 nfit 上 找到更正后的代码:

          for (int n = 0; n < nfit.size(); n++){
              nstore.add(n, nfit.indexOf(nstore.remove(n)));
          }
          

          【讨论】:

            【解决方案5】:

            合并排序的以下实现实现了一个方法'indexSort',它可以做到这一点而不会弄乱输入数组。 http://algs4.cs.princeton.edu/22mergesort/Merge.java.html http://algs4.cs.princeton.edu/code/javadoc/Merge.html#indexSort(java.lang.Comparable[])

            【讨论】:

            • 请在您的答案中包含代码的相关部分,并说明它们如何解决问题。如果这些链接被破坏,仅包含对外部链接的引用的答案将变得过时。 stackoverflow.com/help/how-to-answer
            • 另外,除我之外的所有答案都超出了问题的目的。重新排列索引的复杂性本身就是 O(N^2),比最初的排序要大。
            • 你可以引用别人的代码,只要你把它归于作者。 stackoverflow.com/help/referencing 并尝试坚持所要求的内容; OP 从不将复杂性作为原始问题的一部分..
            【解决方案6】:

            冒泡排序永远是你的朋友。您可以使用它对数组进行排序,同时跟踪原始数组索引。当您的数组中有多个相似元素时,它也可以工作。

            import java.util.*;
            import java.util.Arrays;
            import java.util.Random;
            public class BubbleSort {
                public static void main(String[] args) {
                    Random rnd = new Random();
                    int count = 5;
                    ArrayList<Double> array = new ArrayList<Double>();
                    int[] indices = new int[count];
                    for(int i = 0; i < indices.length; i++) {
                        array.add(rnd.nextDouble() * count);
                        indices[i] = i;
                    }
                    ArrayList<Double> values = new ArrayList<Double>(array);
                    bubbleSort(values, indices);
                    System.out.println("Unsorted input array   :" + array);
                    System.out.print("Sorted   input array   : ");
                    for(int i = 0; i < array.size(); i++) {
                        System.out.print(array.get(indices[i]) + " " );
                    }
                    System.out.println();
                }
                private static void bubbleSort(ArrayList<Double> values, int[] indices) {
                    for(int k = 0; k < values.size(); k++) {
                        for(int l = k + 1; l < values.size(); l++) {
                            if(values.get(k) > values.get(l)) {
                                double temp_value = values.get(k);
                                values.set(k, values.get(l));
                                values.set(l, temp_value);
                                int temp_index = indices[k];
                                indices[k] = indices[l];
                                indices[l] = temp_index;
                            }
                        }
                    }
                }
            }
            

            这么多年后我回答这个问题的原因是,如果您有多个具有相似值的元素,accepted answer 将失败,因为在indexes[n] = nstore.indexOf(nfit.get(n)); 中,indexOf 方法总是返回第一次出现的指定元素导致输入数组中有类似元素的索引数组不正确。

            最后,复制粘贴BubbleSort.java中的代码,然后运行javac BubbleSort.java &amp;&amp; java BubbleSort编译,看看结果。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-01-04
              • 1970-01-01
              • 2014-01-07
              • 1970-01-01
              • 2019-12-08
              • 1970-01-01
              • 1970-01-01
              • 2015-09-16
              相关资源
              最近更新 更多