用于搜索文件名称并获取其路径的数据结构

时间:2017-11-12 01:27:52

标签: optimization data-structures graph trie

我将以动态的方式插入文件名,大约有10亿个名字。此外,我还想存储文件所在的路径,以便进行以下查询:

  • 搜索文件的名称以便获取其路径。
  • 搜索与子字符串匹配的所有文件的名称,有点像查询(例如,如果搜索* o *,它将返回我joel,hola,ola,oso,osea,algo,if a搜索aa *,它会返回我aaab,如果我搜索* so,它将返回oso)。
  • 删除文件名。

所以,我试图通过以下方式构建一种trie数据结构:

我有26个节点(英文字母a-z,我不打算将所有节点放在图像中因为空间),这样如果我插入单词" hola"然后我用节点创建了一个带有字母' h'用字母' o'并且其边缘具有数据1,因为该数字表示深度的级别。此外,在' a'存储,我将有一个地图结构,以存储文件的路径,这是因为我肯定会有很多路径存储在节点中,其中包含字母' a'。

话虽如此,我插入了以下词语:joel,hola,ola,oso,osea,algo,aaab。

enter image description here

我之所以这样做,是因为我不希望有很多带有sama lettres的节点(例如a,b等),但问题是我有很多边缘和sctructure需要

formula

内存字节(我用C ++编程),其中w是一个大小为formula的字符串。

正如你所看到的,如果我搜索文件的名称" jola" (未插入)将不返回任何路径,这告诉我们不存储此类文件。

  

我该如何改进?是否可以减少边缘数量?还是有更好的结构和方法来做到这一点?我很乐意听到任何建议。

2 个答案:

答案 0 :(得分:0)

过去,我已经解决了一个有点类似的问题,用于存储填字游戏的单词表,并且很快找到单词。我称它为“超级索引”。我的主要目标是速度,而不是存储大小,但最初的问题并未说明作者认为什么是“改进”:也许是大小,也许是速度,也许是算法复杂性。我的方法以相对较小的复杂性获得了惊人的速度,但是在存储大小上却节省了相当多的时间。方法如下:

  1. 使用树而不是图形。树中的每个节点最多可包含26个“条目”。每个条目代表字母字母,并包含一个到子节点的链接,或者,如果该条目属于叶节点,则到“有效载荷”(在您的情况下为“路径”)的链接。因此,当节点包含给定字母的条目时,这表示存在一个在该位置具有该字母的“名称”。 (位置是树中节点的深度。)

  2. 按名称长度将所有名称分开,因为这很容易确定。为每个名称长度使用完全独立的树。这意味着在每棵树中,所有叶节点的深度都完全相同,并且树中唯一包含其他数据(在您的情况下为路径)的节点是叶节点。这使事情变得非常简单。

因此,搜索算法如下:

  1. 在所有具有不同名称长度的不同树中,使用与要搜索的“名称”长度相对应的树。
  2. 从您要查找的“名称”的第一个字母开始,并在树的根节点处。
  3. 在当前节点中找到当前字母的条目;如果不存在这样的条目,则找不到名称,完成。否则:
  4. 如果到达叶节点,则找到名称,返回有效载荷,在您的情况下为“路径”。否则:
  5. 移至您要查找的单词的下一个字母;跟随从当前节点中找到的条目到下一个子节点的链接;转到步骤3。

如您所见,这是一个相当简单的算法,而且可以保证非常快。如果没有进一步的优化,则每个存储名称的存储要求将约为一个“条目”,而一个“条目”将由一个字符和一个指针组成。

然后,可以进行多种优化。例如,“ entry”(入口)在推理数据结构时可能是有用的概念,但在实际实现中可以完全消除:在每个节点中,您可以有一个“摘要” 32位机器字,其中每个前26位指示节点中是否存在相应的字母,然后是指向子节点(或有效负载)的指针数组,该子节点包含的元素与摘要字中设置的位一样多。

答案 1 :(得分:-1)

你既可以使用DAG(有向无环图),也可以使用不相交的集合操作技术(快速查找技术(*主要目标是查找))