【问题标题】:Sorting Elements in Place in Java在 Java 中对元素进行就地排序
【发布时间】:2020-06-24 19:28:34
【问题描述】:

我正在尝试通过降低频率对给定元素的列表进行排序。如果两个元素具有相同的频率,它们应该以递增的顺序出现。例如,给定输入:[6, 1000, 3, 3, 1000, 6, 6, 6],输出应为:[6, 6, 6, 6, 3, 3, 1000, 1000]。元素也必须就地排序,而不是返回一个新列表。

到目前为止,我已经创建了一个键和值的 HashMap,其中键是元素,值是频率。但我不太确定下一步该做什么:

public static void method(List<Integer> items)
{
        int size = items.size();
        int count = 0;
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < size; ++i)
        {
            int item = items.get(i);
            if (map.containsKey(item))
            {
                map.put(item, map.get(item) + 1);
            }
            else
            {
                map.put(item, 1);
            }
        }
        List list = new LinkedList(map.entrySet());
        Collections.sort(list, new Comparator()
        {
            public int compare(Object o1, Object o2)
            {
                return ((Comparable) ((Map.Entry) (o1)).getValue())
                .compareTo(((Map.Entry) (o2)).getValue());
            }
        });
        HashMap sortedMap = new LinkedHashMap();
        for (Iterator it = list.iterator(); it.hasNext();)
        {
            Map.Entry entry = (Map.Entry) it.next();
            sortedMap.put(entry.getKey(), entry.getValue());
        }
}

【问题讨论】:

  • 如果两个不同频率出现相同次数的顺序是什么?
  • 不要使用原始类型。你开始得体,但在中间的某个地方迷失了方向。考虑一下这个 - “您需要按 valuereverse order然后按键 对条目进行排序碰撞。”
  • @WJS 我认为问题陈述清楚地总结在行 “我正在尝试通过降低频率对给定元素的列表进行排序。如果两个元素具有相同的频率,它们应该出现以递增的顺序。” 然后示例输出[6, 6, 6, 6, 3, 3, 1000, 1000] 进一步澄清了它。

标签: java sorting hashmap frequency comparator


【解决方案1】:

您可以按如下方式进行内联排序:

public static void sortInline(List<Integer> list) {
    Map<Integer, Long> map = list.stream()
            .collect(Collectors.groupingBy(Function.identity(),
                    Collectors.counting())); // frequency map
    Comparator<Integer> frequencyComparison = Comparator
            .<Integer>comparingLong(map::get).reversed(); // sort the entries by value in reverse order 
    list.sort(frequencyComparison.thenComparing(Comparator.naturalOrder())); // then by key for the collisions
}

【讨论】:

    【解决方案2】:
    public static void method(List<Integer> list) {
        Map<Integer, Long> map = list.stream()
                                     .collect(Collectors.groupingBy(Function.identity(), 
                                                                    Collectors.counting()));
        list.sort(new Comparator<Integer>() {
             @Override
             public int compare(Integer o1, Integer o2) {
                 Long cnt1 = map.get(o1);
                 Long cnt2 = map.get(o2);
                 int compare = cnt2.compareTo(cnt1);
                 if (compare == 0) {
                     return o1.compareTo(o2);
                 }
                 return compare;
             }
        });
    }
    

    【讨论】:

    • 我在map.get(o1)map.get(o2) 这行遇到错误——“long 无法转换为整数”
    • 很抱歉。我更新了地图创建以避免手动操作并忘记更新比较器。
    猜你喜欢
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多