是否可以使用搜索功能枚举集合中的所有项目

时间:2018-12-20 01:35:01

标签: algorithm search heuristics

我正在寻找一种算法,也许是启发式算法来解决以下问题。

是否可以使用搜索功能枚举集合中的所有项目? 是否有任何已知的算法/启发式方法可以做到这一点?

例如,根据以下条件:

  • 有一个API,可以按标题搜索歌曲。
  • 不区分大小写。
  • 搜索匹配歌曲标题的任何部分,它可以匹配歌曲开头和中间的部分。
  • 如果搜索词组为null,则返回前100名。
  • 歌曲由SongOrder属性排序。
  • 它仅返回前100名。
  • 最有可能在其中最多容纳数千首歌曲 数据库。但是消费者不知道歌曲的实际数量 下面的功能。
  • 这是一个现实生活中的问题,无法更改搜索功能。

搜索功能的伪实现如下所示:

List<Song> FindSongs(string searchText)
{
    var allSongs = LoadAllSongsFromDB();
    var allSongsOrderedBySongOrder = allSongs.OrderBy(x => x.SongOrder);
    var matchingSongs = allSongsInDatabase.Where(song => searchText == null || song.Title.Contains(searchText));
    var topHundred = matchingSongs.Take(100);
    return topHundred.AsList();
}

class Song
{
    public int Id;
    public string Title;
    public int SongOrder;
}

2 个答案:

答案 0 :(得分:0)

首先搜索单个字母。例如,搜索“ A”可能会返回100首歌曲,但是搜索“ Z”可能会返回不到100首歌曲。

然后为每个返回100首歌曲的字母添加另一个字母。例如,假设搜索“ A”返回100首歌曲,则搜索“ AA”,“ AB”,“ AC”等。

任何返回100首歌曲的搜索都需要通过添加另一个字母来完善。返回少于100首歌曲的搜索已完成:删除重复的歌曲可以将其添加到输出列表中。

答案 1 :(得分:0)

如果存在 数据库,则最好让数据库负责过滤,而不是在代码中进行过滤-如果数据库进行过滤,则不进行过滤必须将所有歌曲发送到您的代码中,这样既节省了时间,又不会使网络过载(想象许多用户同时执行此操作)。数据库还可以在文本字段上建立索引(尽管它们通常不会费心构建对于该用例最有用的索引),因此它们也可以比代码更有效或更快速地找到文本。

在数据库中排名前100名将再次节省时间和网络流量,因此我的伪代码(受Java JPA启发)将简单地让数据库完成所有工作:

PreparedStatement queryByTitle = myDatabase.prepareQuery(
    """SELECT * 
     FROM Songs
     WHERE title LIKE '%:partOfTitle%' 
     ORDER BY songOrder
     LIMIT 100"""
    ).withStringParameter("partOfTitle");


PreparedStatement queryWithoutTitle = myDatabase.prepareQuery(
    """SELECT * 
     FROM Songs
     ORDER BY songOrder
     LIMIT 100""")

List<Song> getSongs(String partOfTitle) {
    if (partOfTitle.isEmpty()) {
       return myConnection.executePreparedQuery(queryWithoutTitle));
    } else {
       return myConnection.executePreparedQuery(
          queryWithTitle, partOfTitle));
    }
}

如果您需要使用数据库中返回的大量歌曲来执行代码中的所有操作,则您所做的任何事情都最多为O(返回的歌曲数)(因为这是获得大型歌曲的代价)首先是数据库中的列表),因此没有哪种O(n)算法会比其他任何算法都快得多。

如果没有 数据库,并且您始终将本地内容存储在一个大列表中,那么您可以比O(n)做得更好

  1. 保留按受欢迎程度排序的歌曲列表
  2. 构建所有歌曲标题的trie,以获得有效的O(k)搜索时间,搜索标题的长度k个部分。