根据任意规则将(混合)项目插入到数组中

时间:2013-12-10 01:47:21

标签: arrays algorithm sorting ranking

由于我对算法的经验很少,所以我真的用头撞墙了。

考虑一个应用程序,它维护一组电视节目和这些节目的剧集。允许用户对节目进行排名(排名,而不是费率;因此从0到n-1,0为最高排名)。

该应用程序旨在根据节目的排名显示剧集列表。在任何给定时间,应用将在每个节目的列表中显示0,1或2集(即,如果用户观看了TheFooShow的所有剧集,则列表中不会出现剧集;如果她有10集未观看TheBarShow的剧集,两个将出现在列表中)。这些剧集将被视为primarysecondary

列表中的剧集排序应尽可能遵守一些规则:

  • 列表中节目的主要剧集应出现在任何排名较低的节目集之前
  • 节目的次要剧集不应出现在同一节目的主要剧集之前
  • 如果可能的话,节目的两个剧集不应该在彼此的4个位置内
  • 节目的次要剧集可以在节目的主要剧集排名七位或更多位置之前出现

这里的观点是,高排名节目的剧集将在排名较低的节目之前列出,但仅限于在可能的情况下引入一定数量的节目的程度。

示例集可以是(不严格遵循上述规则):[0, 1, 3, 0', 3', 4, 5, 10, 4', 11, 11', 23]

从头开始构建列表,添加所有主要剧集,然后根据需要插入辅助剧集,我可以接近达到预期的效果。不幸的是,鉴于应用程序的其余部分如何工作,我需要能够将剧集插入已经构建的列表中。

鉴于基础剧集数据如何变化,每当需要插入一集时,列表中已有的所有剧集将被删除,该节目的当前剧集将被发现,而他们(或它)将背靠背插入。

我基本上喜欢这样的功能:

- (int, int)indexesForEpisodesFromShow:(TVShow)aShow currentList:(List)aList

可以在任何州获取列表,并且在给定节目的情况下,采取适当的剧集并确定列表中应插入的位置。

我目前的解决方案相当原始,正如我所说,只适用于某些情况。我尝试过更复杂的其他解决方案(阅读:if语句更多),但它们往往变得非常脆弱,当我添加额外的复杂性来处理边缘情况时,测试开始与其他测试相矛盾。

我觉得我想要实现的规则类型,以及有多少规则,这应该是可以解决的,但经过多次尝试后我仍然被卡住了。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我认为您需要的只是比较两集的功能。

首先让我们做一些假设:

  • 剧集的对象有两个属性:
    1. 显示:剧集属于
    2. 的节目对象
    3. IsPrime:剧集是否为主要
  • 并且show对象有一个属性:
    1. 排名:该节目的排名

然后,让我们创建一个具有两个剧集对象作为输入参数的函数,并返回:

  • -1:第一集必须放在第二集之前。
  • 0:这两集可以按任何顺序定位。
  • 1:第一集必须在第二集之后定位。

    CompareEpisode(e1, e2)
    {
      if(e1.IsPrime)
      {
        if(e2.IsPrime)
          return CompareSame(e1, e2);
        else
          return CompareDiff(e1, e2);
      }
      else
      {
        if(e2.IsPrime)
          return -CompareDiff(e2, e1);
        else
          return CompareSame(e1, e2);
      }
    }
    
    CompareSame(e1, e2)
    {
      if(e1.Show.Rank < e2.Show.Rank)
        return -1;
      else if(e1.Show.Rank == e2.Show.Rank)
        return 0;
      else
        return 1;
    }
    
    CompareDiff(p, s)
    {
      if(p.Show == s.Show)
        return -1;
      else
      {
        if(p.Show.Rank < s.Show.Rank + 7)
          return -1;
        else if(p.Show.Rank == s.Show.Rank + 7)
          return 0;
        else
          return 1;
      }
    }
    

现在你可以迭代列表,使用CompareEpisode将列表中的每个元素与插入的剧集进行比较,找到第一个元素使CompareEpisode返回0或1,你可以在元素找到之前插入新的剧集。

如果有一些元素使得CompareEpisode返回0,你就会得到多个候选位置,你可以选择一个适合“从同一个节目中放置剧集”的规则。