【问题标题】:How do I pick a selection of rows with the minimum date difference如何选择日期差异最小的行
【发布时间】:2011-04-20 10:43:30
【问题描述】:
这个问题很难表达。希望这会有意义。
我的库存中有一个项目表。
我们将这些项目称为 Apple、Orange、Pear、Potato。我想挑一篮水果(1 x 苹果,1 x 橙子,1 x 梨)。
库存中的每件商品都有不同的可用日期。所以……
- 苹果一月
- 苹果二月
- 苹果三月
- 橙色 四月
- 苹果四月
- 梨可能
我不想按照物品在库存中出现的顺序来挑选物品。相反,我想根据可以选择所有项目的最小日期范围来选择它们。即四月的橙苹果和五月的梨。
我不确定这是否是 MYSQL 或某些 PHP 数组的问题。我难住了。提前致谢。
【问题讨论】:
标签:
php
mysql
arrays
algorithm
【解决方案1】:
鉴于您的表库存是结构化的:
fruit, availability
apple, 3 // apples in march
//user picks the availability month maybe?
$this_month = 5 ;
//or generate it for today
$this_month = date('n') ;
// sql
"select distinct fruit from inventory where availability = $this_month";
【解决方案2】:
如果水果数组尚未按日期排序,让我们对其进行排序。
现在,简单的 O(n^2) 解决方案是检查所有可能的范围。没有特定语言的伪代码:
for (int i = 0; i < inventory.length; ++i)
hash basket = {}
for (int j = i; j < inventory.length; ++j) {
basket.add(inventory[j]);
if (basket.size == 3) { // or whatever's the number of fruits
// found all fruits
// compare range [i, j] with the best range
// update best range, if necessary
break;
}
}
end
您可能会发现它已经足够好了。
或者你可以写一个更复杂的 O(n) 解决方案。这只是一个滑动窗口[first, last]。在每一步,我们移动左边界(不包括篮子中的一个水果)或右边界(向篮子中添加一个水果)。
int first = 0;
int last = 0;
hash count = {};
count[inventory[0]] = 1;
while (true) {
if (count[inventory[first]] > 0) {
--count[inventory[first]];
++first;
} else if (last < inventory.length) {
++last;
++count[inventory[last]];
} else {
break;
}
if (date[last] - date[first] < min_range
&& count.number_of_nonzero_elements == 3) {
// found new best answer
min_range = date[last] - date[first]
}
}
【解决方案3】:
听起来很复杂。我解决问题的方法是将每个水果分组到其可用月份组中,然后查看每个组中有多少。
- 一月 (1)
- 二月 (1)
- 三月 (1)
- 四月 (2)
- 五月 (1)
看到最多的水果落在 APRIL 之内。因此,APRIL 是我们的首选月份。
然后,我会从具有重复项的月份中删除这些项目(在您的示例中为 Apples),这将删除 MARCH 作为一个选项。此步骤可以现在完成,也可以在下一步之后完成,具体取决于您的数据和获得的结果。
然后我会查看下一个最受欢迎的月份并计算该月的距离(例如,JAN 距离 APRIL 3 天,MARCH 距离 APRIL 3 号,等等)。如果您当时打了领带,那么您选择哪个并不重要。在此示例中,尽管您最终会按照您的要求选择 APRIL 的 2 种水果和 MAY 的 1 种水果。
如果最受欢迎的月份实际上并未产生“最佳”选择,则此方法可能不起作用。