【问题标题】: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 梨)。

库存中的每件商品都有不同的可用日期。所以……

  1. 苹果一月
  2. 苹果二月
  3. 苹果三月
  4. 橙色 四月
  5. 苹果四月
  6. 可能

我不想按照物品在库存中出现的顺序来挑选物品。相反,我想根据可以选择所有项目的最小日期范围来选择它们。即四月的橙苹果和五月的梨。

我不确定这是否是 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)
        2. 二月 (1)
        3. 三月 (1)
        4. 四月 (2)
        5. 五月 (1)

        看到最多的水果落在 APRIL 之内。因此,APRIL 是我们的首选月份。

        然后,我会从具有重复项的月份中删除这些项目(在您的示例中为 Apples),这将删除 MARCH 作为一个选项。此步骤可以现在完成,也可以在下一步之后完成,具体取决于您的数据和获得的结果。

        然后我会查看下一个最受欢迎的月份并计算该月的距离(例如,JAN 距离 APRIL 3 天,MARCH 距离 APRIL 3 号,等等)。如果您当时打了领带,那么您选择哪个并不重要。在此示例中,尽管您最终会按照您的要求选择 APRIL 的 2 种水果和 MAY 的 1 种水果。

        如果最受欢迎的月份实际上并未产生“最佳”选择,则此方法可能不起作用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-11
          • 1970-01-01
          • 2016-01-15
          • 2020-06-27
          • 2018-09-13
          • 1970-01-01
          • 2015-07-23
          相关资源
          最近更新 更多