【问题标题】:Sorting a list based on frequency of words根据单词的频率对列表进行排序
【发布时间】:2014-03-22 03:25:04
【问题描述】:

我需要根据频率对单词列表进行排序。

我的意见:

Haha, hehe, haha, haha, hehe, hehe.... , Test

例如在我的数据结构中,我会有

Haha:3
Hehe:5
Test:10 

我需要以这种方式在输出中对数据结构进行排序:

Test:10
Hehe:5
Haha:3

这样,如果我弹出数据结构的顶部,我将能够获得元素及其相应的频率。

元素的数量最初是未知的,因此数组是不可行的。如果我想获得前几个元素,我只需要按顺序访问它。这在 Java 中可行吗?

【问题讨论】:

  • 是的,有可能。你有没有尝试过任何方法?
  • @juan.facorro,是的,我做到了。我尝试将数字附加到字符串末尾以逗号分隔的字符串,然后将其提取出来以再次递增。但是,这证明对列表进行排序是一个问题。
  • 您可以使用Map 存储键值对,并且可以按值对其进行排序。看看答案..here

标签: java data-structures word-list


【解决方案1】:

首先,要确认: 你能在排序之前得到所有的单词吗?还是这些词连续出现?

(1)对于前一种情况,您可以使用Set 来存储单词,然后将它们放入PriorityQueue。如果你实现了比较器功能,队列会自动对单词进行排序。我新建一个类Pair来存储文本和频率,见代码:

import java.util.Queue;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.HashSet;
import java.util.Comparator;

public class PriorityQueueTest {

    public static class Pair {
        private String text;
        private int frequency;

        @Override
        public int hashCode() {
            return text.hashCode();
        }

        @Override
        public String toString() {
            return text + ":" + frequency;
        }

        public Pair(String text, int frequency) {
            super();
            this.text = text;
            this.frequency = frequency;
        }

        public String getText() {
            return text;
        }
        public void setText(String text) {
            this.text = text;
        }
        public int getFrequency() {
            return frequency;
        }
        public void setFrequency(int frequency) {
            this.frequency = frequency;
        }
    }

    public static Comparator<Pair> idComparator = new Comparator<Pair>(){
        @Override
        public int compare(Pair o1, Pair o2) {
            if(o1.getFrequency() > o2.getFrequency()) {
                return -1;
            }
            else if(o1.getFrequency() < o2.getFrequency()){
                return 1;
            }
            else {
                return 0;
            }
        }
    };

    public static void main(String[] args) {
        Set<Pair> data = new HashSet<Pair>();
        data.add(new Pair("haha", 3));
        data.add(new Pair("Hehe", 5));
        data.add(new Pair("Test", 10));

        Queue<Pair> queue = new PriorityQueue(16, idComparator);

        for(Pair pair : data) {
            queue.add(pair);
        }

        // Test the order
        Pair temp = null;
        while((temp = queue.poll()) != null) {
            System.out.println(temp);
        }

    }

}

(2)对于其他情况(单词连续出现),您可以使用TreeMap 来保持顺序。 见参考:http://www.java-samples.com/showtutorial.php?tutorialid=370

【讨论】:

  • 为什么有 hashCode 但没有 equals?
【解决方案2】:

为了保留您需要的信息,您可以创建一个类来保存您的字符串和计数(例如 Pair)并将此类的实例保存在 List&lt;Pair&gt; 中。这种方法会使给定字符串的计数增加效率低下,因为您必须在线性时间 (O(N)) 中查找保存该字符串的元素,然后再增加它。

更好的方法是使用Map&lt;String, Integer&gt;,这样搜索在恒定时间内完成(O(1)),然后您可以对返回的Set&lt;Map.Entry&lt;String, Integer&gt;&gt; 中的元素进行排序Map.entrySet().

【讨论】:

    【解决方案3】:
    1. 列表项

    我从下面的 URL 作为参考开始,我将在该参考的基础上进行构建:

    How can I count the occurrences of a list item in Python?

    现在,建筑开始了:

    >>> from collections import Counter
    >>> word_list = ['blue', 'red', 'blue', 'yellow', 'blue', 'red','white','white']
    >>> Counter(word_list)
    Counter({'blue': 3, 'red': 2, 'white': 2, 'yellow': 1})
    

    注意 Counter(word_list) 如何显示元素列表,即按频率降序排列的单词/频率对。不幸的是,提取单词并将它们编译到按相同顺序排序的列表中需要更多的工作:

    (1) 获取“大小”作为 JSON 对象中的元素个数。

    (2) 对 JSON 对象应用“most_common”方法,以获取按频率排序的元素数组。

    (3) 应用列表推导生成从排序数组中提取的单词列表。

    >>> size = len(Counter(word_list))
    4
    >>> word_frequency_pairs = Counter(word_list).most_common(size)
    >>> word_frequency_pairs
    [('blue', 3), ('white', 2), ('red', 2), ('yellow', 1)]
    >>> [i[0] for i in word_frequency_pairs]
    ['blue', 'white', 'red', 'yellow']
    

    我喜欢 Python 是有原因的 :)

    【讨论】:

    • 问题是关于 Java 的。您提供了一个 python 解决方案并为此感到自豪。这就像问某人“你知道如何骑自行车吗?”他们回复“这是如何做背击”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2019-06-10
    • 2013-12-28
    相关资源
    最近更新 更多