给定对象列表,提取具有相似大小的N个对象

时间:2013-05-24 17:02:10

标签: c# java algorithm pattern-matching

我有一个2D空间中的对象列表,每个对象当然都有一个XY位置,一个宽度和高度。

我想提取大小相近的N个对象。

例如:

Size Object 1 : 100 (10 W x 10 H)

Size Object 2 : 150

Size Object 3 : 140

Size Object 4 : 160

Size Object 5 : 140

在这种情况下,对于N = 4,返回列表将是:Objects: {2,3,4,5}

我的想法是计算平均大小并逐个获得与平均值最接近的对象。 但是当有大的物体升高平均值时,这种方法会失败。

有什么建议吗?

谢谢大家!

2 个答案:

答案 0 :(得分:3)

第一步是按大小对输入数组进行排序。然后,迭代遍历数组,同时保持一组“最相似”的元素,但是你要定义它。假设一组N个元素是“最相似的”,如果它最小化集合中最小元素和最大元素之间的差异,那么你的算法将看起来像

Deque leastSet = new LinkedList(); // use a Deque instead of a Set because order is important, and presumably your inputArray doesn't contain duplicates anyway; if the input may contain duplicates, then use a LinkedHashSet instead
Deque currentSet = new LinkedList();

// initialize deques with first N elements
for(int i = 0; i < N; i++) {
    leastSet.addLast(inputArray[i]);
    currentSet.addLast(inputArray[i]);
}

for(int i = N; i < inputArray.length; i++) {
    currentSet.removeFirst();
    currentSet.addLast(inputArray[i]);
    if((currentSet.peekLast() - currentSet.peekFirst()) < (leastSet.peekLast() - leastSet.peekFirst())) {
        leastSet = currentSet.clone();
    }
}

答案 1 :(得分:0)

蛮力是从最小值到最大值创建一组桶(列表数组)。以delta为1开始。循环遍历每个元素并将其放入每个桶中,从val-delta到val + delta。确定任何存储桶是否包含n个元素。如果不将delta增加1并重复。

另一个(可能更好的选择)。按大小排序。从像1开始的小maxdelta开始。然后查看每个元素(i)和元素(i + n)。如果我和i + n的delta小于maxdelta这是你的集合(或至少是你的集合的开头,因为可能有其他元素)。如果不增加我。如果没有找到设置增量maxdelta并重复。