Python 在mp3播放器中实现歌曲搜索功能的数据结构?

Python 在mp3播放器中实现歌曲搜索功能的数据结构?,python,algorithm,search,data-structures,Python,Algorithm,Search,Data Structures,我正在制作自己的mp3播放器。对于mp3播放器,我需要一个与VLC Media player和Rhythmbox以及其他媒体播放器相同的歌曲搜索功能,在该功能中,可以通过指定艺术家/曲目/专辑名称来搜索歌曲 例如,这是4首具有各自元数据的歌曲。 Track Artist Album Dear Agony Breaking Benjamin

我正在制作自己的mp3播放器。对于mp3播放器,我需要一个与VLC Media player和Rhythmbox以及其他媒体播放器相同的歌曲搜索功能,在该功能中,可以通过指定艺术家/曲目/专辑名称来搜索歌曲

例如,这是4首具有各自元数据

的歌曲。
Track                     Artist                            Album

Dear Agony                Breaking Benjamin                 Test Name
Radioactive               Imagine Dragons                   Billboard
Feel Good Drag            Anberlin                          Random
Khamaj                    Fuzon                             Tere Liye
现在假设我给出搜索查询:
ag
,那么结果应该是:

Dear Agony                Breaking Benjamin                 Test Name
Radioactive               Imagine Dragons                   Billboard
Feel Good Drag            Anberlin                          Random
因为前三首歌在元数据中出现了一些
ag
,但是第四首歌没有,因此不应该列出

所有的mp3文件中都有这些数据,我知道如何从中提取这些数据。真正的挑战是使用哪种数据结构以及如何使用该数据结构来实现这一点


特别是如果用户的歌曲播放列表非常大,则需要高效地检索结果。请建议一些我可以实现的数据结构来实现这一点。顺便说一句,我正在使用Python

如果您打破所有数据(曲目名称、乐队、唱片集)的单词列表,您可以使用一个哈希表,该哈希表由单词索引,并使用一个链接列表作为包含所有出现该事件的曲目的值

对于搜索,您可以使用B+树对单词进行索引,以获取哈希表的键(或多或少类似于文字处理器对自动更正的处理)


干杯

如果你打破了所有数据(曲目名称、乐队、专辑)的单词列表,你可以有一个由单词索引的哈希表,其中链接列表作为包含所有出现该事件的曲目的值

对于搜索,您可以使用B+树对单词进行索引,以获取哈希表的键(或多或少类似于文字处理器对自动更正的处理)


当然,最简单的方法是按顺序搜索记录,使用
字符串。包含对每个记录的每个字段的
检查。如果所有的元数据都在内存中,那么即使您有成千上万首歌曲,这也不是非常低效。记住,这不一定是盲目的快。用户可能愿意等待几百毫秒的结果

这实际上取决于您如何构建用户界面。例如,如果用户键入
“a”
,则必须浏览整个歌曲列表,才能在元数据中的任何位置找到包含该字母的歌曲。如果用户随后键入
“g”
,则不必浏览整个歌曲列表。您只需查看已有的列表:以“
a
”开头的列表。考虑到英语中最常见的二元结构(“th”)出现在大约2.5%的单词中,当用户键入两三个字符时,您正在处理的列表非常小(最多几百个项目),以至于简单的顺序搜索足够快

如果你想做得更快,你必须构建一个trie并插入每个n-gram。接受状态包含包含该n-gram的记录列表。构建需要一段时间,并且由于接受状态的所有引用,结果数据结构相当大。即使经过优化,特定单词的每个字母都有一个参考。例如,单词“Agony”最后有五个参考。在添加或删除歌曲时更新trie并不特别困难

您可以使用字典或散列映射做同样的事情,使用n-gram作为键,但是组合引用要困难得多。使用字典,“Agony”一词最终会在地图中存储一个“a”、“ag”、“ago”的参考。。。“o”、“on”、“ony”、“n”、“ny”、“y”。因此,不是每个单词的
length
引用,而是每个单词的
(length^2-length)/2个
引用

我曾经使用过混合方法。我建立了一个包含引用的bigram树,这样我就可以很快地对前两个字母进行初始查找。然后我会按顺序搜索这些结果。因此,如果用户键入“ago”,我将转到trie并找到元数据中包含“ag”的所有项。然后,我会按顺序搜索这些项目中的“ago”。因为第二个列表通常相对较小,所以速度惊人。而建造一个大型实验室并没有占用大量的空间


我的建议是首先构建顺序搜索。然后,如果速度太慢,执行上面的混合方法。

当然,最简单的方法是顺序搜索记录,对每个记录的每个字段执行
字符串检查。如果所有的元数据都在内存中,那么即使您有成千上万首歌曲,这也不是非常低效。记住,这不一定是盲目的快。用户可能愿意等待几百毫秒的结果

这实际上取决于您如何构建用户界面。例如,如果用户键入
“a”
,则必须浏览整个歌曲列表,才能在元数据中的任何位置找到包含该字母的歌曲。如果用户随后键入
“g”
,则不必浏览整个歌曲列表。您只需查看已有的列表:以“
a
”开头的列表。考虑到英语中最常见的二元结构(“th”)出现在大约2.5%的单词中,当用户键入两三个字符时,您正在处理的列表非常小(最多几百个项目),以至于简单的顺序搜索足够快

如果你想做得更快,你必须构建一个trie并插入每个n-gram。接受状态包含包含该n-gram的记录列表。构建需要一段时间,并且由于接受状态的所有引用,结果数据结构相当大。即使优化,也有一个参考