TreeSet:有效小于某个值的元素数

时间:2015-12-23 02:35:40

标签: java count subset treeset

我需要一种方法来快速计算TreeSet整数中小于X的元素数。

我可以使用

  • 子集()
  • headSet()
  • tailSet()

方法,但它们真的很慢(我只需要计数,而不是数字本身)。有办法吗?

谢谢。

编辑:

我发现了一种使事情变得更快的解决方法!我正在使用BitSet和它的cardinality()方法。我首先创建一个BitSet,并且对于添加到TreeSet的每个元素,我在BitSet中设置相应的索引。现在,要计算小于X的元素数量,我使用:

bitset.get(0,X + 1)。cardinality()

与treeset.subSet(0,true,X,true).size()相比,这要快得多。

任何人都知道为什么?我假设BitSet.cardinality()不使用线性搜索。

4 个答案:

答案 0 :(得分:2)

'真快的速度'需要?你有多少元素?

currentTextField是O(1),因为它们会返回原始树集的视图,但是如果你subSet()/headSet()/tailSet()你的size()你仍在迭代所有原始元素,那么O( N)。

您使用的是Java 8吗?这将大致相同,但您可以将成本并行化。

subSet()

NB EDIT

通过进一步的探索和测试,我无法证实这一说法&#34;如果你Set<Integer> set = new TreeSet<>(); // .. add things to set long count = set.parallelstream().filter(e -> e < x).count(); 你的size()你还在迭代所有原始元素&#34;。我错了。这个4核心机器上的subSet()parallelstream().count()

慢约30%

答案 1 :(得分:2)

如果不更新数据结构,只需在hashmap中保留小于X的元素数量!

如果不经常更新,请保留已排序的数字链表。在插入/删除时,在O(1)中的列表中添加/删除并更新散列映射(O(n))。

您可以使用(已排序)二叉树来更新O(Log(n))和O(Log(n))。在树的每个元素中,还保留其后代的数量。现在获得#items&lt;比y,你在二叉树中找到它,但是当你向右而不是向左时,也要求元素的数量。在更新时,您还需要更新新元素的祖先。

顺便说一下,如果你愿意接受大概的答案,那么也可能有更快的方法。

答案 2 :(得分:2)

由于到目前为止所有答案都指向与Java TreeSet不同的数据结构,我建议使用Fenwick树,它有O(log(N))用于更新和查询;请参阅link了解Java实现。

答案 3 :(得分:-1)

package ArrayListTrial;

import java.util.Scanner;

public class countArray {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int[] array = new int[100];
        Scanner scan = new Scanner(System.in);
        System.out.println("input the number you want to compare:");
        int in = scan.nextInt();
        int count = 0;
        System.out.println("The following is array elements:");
        for(int k=0 ; k<array.length ; k++)
        {
            array[k] = k+1;
            System.out.print(array[k] + " ");
            if(array[k] > in)
            {
                count++;
            }
        }
        System.out.printf("\nThere are %d numbers in the array bigger than %d.\n" , count , in);

    }

}