java - 跟踪在 Java 中解析流时找到的最多 5 个值的最佳方法

标签 java parsing data-structures

我正在逐行解析一个大文件,读取每行中的子字符串。我将从每个子字符串中获取一个整数值,每行约 30 个,并且需要从文件中返回最高的 5 个值。哪种数据结构最有效地跟踪遍历过程中的 5 个最大值?

最佳答案

这个问题通常用 heap, 解决。但是(也许违反直觉)你使用了一个最小堆(最小的元素是堆的“顶部”)。

算法基本上是这样的:

   for each item parsed
      if the heap contains less than n items, 
         add the new item to the heap
      else
         if the new item is "greater" than the "smallest" item in the heap
            remove the smallest item and replace it with the new item

When you are done, you can pop the elements off the heap from least to greatest.

Or, concretely:

  static <T extends Comparable<T>> List<T> top(Iterable<? extends T> items, int k) {
    if (k < 0) throw new IllegalArgumentException();
    if (k == 0) return Collections.emptyList();
    PriorityQueue<T> top = new PriorityQueue<>(k);
    for (T item : items) {
      if (top.size() < k) top.add(item);
      else if (item.compareTo(top.peek()) > 0) {
        top.remove();
        top.add(item);
      }
    }
    List<T> hits = new ArrayList<>(top.size());
    while (!top.isEmpty())
      hits.add(top.remove());
    Collections.reverse(hits);
    return hits;
  }

您可以将新项目与 top of the heap efficiently, 进行比较并且您不需要始终保持所有元素严格排序,因此这比完全有序的集合(如 TreeSet)更快。

对于包含五个元素的非常短的列表,遍历数组可能会更快。但是,如果“top hits”集合的大小增长,这种基于堆的方法将会胜出。

关于java - 跟踪在 Java 中解析流时找到的最多 5 个值的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38090156/

相关文章:

java - 来自用字段值初始化的数组的 ArrayIndexOutOfBoundsException

java - Jboss一步步设置热部署

javascript - JavaScript 中有值索引集合吗?

c++ - 红黑树插入问题

java - 如何使用在 Scanner 类的另一个类中创建的方法来向该方法提供数据?

java - 及时为大量数据库请求配置Spring JPA和PostgreSQL

r - 如何将制表符分隔的数据(不同格式)解析为 data.table/data.frame?

html - 不插入 HTML 全局结构(如 &lt;!DOCTYPE>、<body>)的 HTML 命令行整洁

parsing - 用于与嵌入式设备传输数据的最有效格式

c - 为什么我得到 "ERROR : request for member stringLength and name in something not a structure or union"?