在ArrayList <object []> </object []>中构造对象的频率表

时间:2011-01-10 11:05:32

标签: java algorithm frequency

我尝试在Java中实现Incognito k-anonymization algorithm。 该算法的一部分是给定表的频率集构造。表的列每次都有所不同,所以我决定将表表示为Object []的ArrayList,其中Object [] size是列的数量。在此对象中,我存储每列的每一行的值。

我尝试使用以下方法构建频率表:

ArrayList<Object[]> table = new ArrayList<Object[]>();
....// table filling//.....
ArrayList<Object[]> frequencySet = new ArrayList<Object[]>();
for(int i=0;i<table.size();i++)
     {
         Integer count = 1;
         int j = 0;
         for(j=i+1;j<table.size();j++)
         {
             if(Arrays.equals(table.get(i), table.get(j)))
             {
                 //System.out.println(i+" equals to "+j);
                 count++;
                 table.remove(j);
                 j = j-1;
             }
         }
         int size = arguments.size()+1;
         Object[] anObject = new Object[size];
         System.arraycopy(table.get(i), 0, anObject, 0, arguments.size());
         anObject[size-1] = count;
         frequencySet.add(anObject);
     }

问题是算法非常慢,我发现在这种方法中大部分时间都消耗了。 (对于100.000数据,它需要13分钟才能运行 - 我不知道这是否正常)。有没有更快的方法来构建频率表?

2 个答案:

答案 0 :(得分:3)

永远不要在remove上使用ArrayList,它是O(size())。此外,每次递增时,count计数变量都会被包装和解包。设置其类型int并仅在最后将其包装到Integer

在不知道您存储的对象类型的情况下,我假设为它们重新定义了方法equalshashCode。然后想到的最好的事情是将Object的数组包装到一个Row类中(无论如何都要做好事),重新定义equals和hashCode for Row(使用Arrays.equals和Arrays.hashCode)并计算每个的出现次数。使用

HashMap<Row, Integer> count;

进行一次传递

for (Row row : table) {
    if (count.containsKey(row)) {
        count.put(row, count.get(row) + 1);
    } else {
        count.put(row, 1);
    }
}

答案 1 :(得分:1)

对它们进行排序,然后用循环计算重复次数。这将把它降低到O(n log n)

或使用散列表来进行计数。那应该是线性时间计算。