Dictionary 在一本大词典中查找一个单词的存在
假设我有一个包含2亿个单词的大字典,我的函数需要检查字典中是否存在任何给定的单词,最快的方法是什么?你不能将字典存储在内存中,因为你只有1GB的内存。您可以将其存储在数据库中,但是如果不进行任何优化,查询它的速度仍然非常慢。因为没有足够的资源,所以无法索引完整单词Dictionary 在一本大词典中查找一个单词的存在,dictionary,Dictionary,假设我有一个包含2亿个单词的大字典,我的函数需要检查字典中是否存在任何给定的单词,最快的方法是什么?你不能将字典存储在内存中,因为你只有1GB的内存。您可以将其存储在数据库中,但是如果不进行任何优化,查询它的速度仍然非常慢。因为没有足够的资源,所以无法索引完整单词 编辑:除了下面提到的文件优化方法外,还有数据库优化吗?我在考虑创建部分索引,比如说,对于单词中的每两个字母,我创建一个索引。这会加速db查询吗?使用Boyer–Moore字符串搜索算法 如果没有索引,只需使用流即可 有时候,最简单的解
编辑:除了下面提到的文件优化方法外,还有数据库优化吗?我在考虑创建部分索引,比如说,对于单词中的每两个字母,我创建一个索引。这会加速db查询吗?使用Boyer–Moore字符串搜索算法
如果没有索引,只需使用流即可 有时候,最简单的解决方案就是最好的
public Int32 IndexOf(FileStream file, Byte[] ascii_bytes, Int32 start_index)
{
Int32 index = -1;
{
Int32 current = 0;
Int64 original_index = 0;
Boolean found = true;
file.Position = start_index;
current = file.ReadByte();
while (current >= 0)
{
if ((Byte)current == ascii_bytes[0])
{
found = true;
original_index = file.Position - 1;
for (Int32 i = 1; (i < ascii_bytes.Length && current > 0); i++)
{
current = file.ReadByte();
if ((Byte)current != ascii_bytes[i])
{
file.Position--;
found = false;
break;
}
}
if (found)
{
file.Position = original_index;
index = (Int32)original_index;
break;
}
}
current = file.ReadByte();
}
}
return index;
}
public Int32 IndexOf(文件流文件,字节[]ascii\u字节,Int32 start\u索引)
{
Int32指数=-1;
{
Int32电流=0;
Int64原始索引=0;
布尔值=真;
file.Position=start\u索引;
当前=file.ReadByte();
而(当前>=0)
{
如果((字节)当前==ascii_字节[0])
{
发现=真;
原始索引=file.Position-1;
对于(Int32 i=1;(i0);i++)
{
当前=file.ReadByte();
如果((字节)当前!=ascii_字节[i])
{
file.Position--;
发现=错误;
打破
}
}
如果(找到)
{
file.Position=原始索引;
索引=(Int32)原始索引;
打破
}
}
当前=file.ReadByte();
}
}
收益指数;
}
二进制搜索
假设字典中的单词按字母顺序排列,我会尝试修改。通过跳转到文件中的中点位置并查看其中的单词来分割和征服文件。如果猜测为“高”,请将较低的部分一分为二,然后重试,直到没有可尝试的文件位置或找到单词为止
(例如,跳转到文件位置后,需要前后扫描以找到跳转到的单词的边界。)
您可以通过根据单词的第一个字母猜出一个位置块来优化它。例如,如果单词以“c”开头,请在文件的3/26部分开始搜索。不过,事实上,我认为这一早期的猜测总体上只会产生微不足道的影响
其他优化可能包括保留索引的一小部分。例如,保留以字母表中每个字母开头的第一个单词的索引,或保留以每个可能的两个字母组合开头的每个单词的索引。这将允许您立即缩小搜索区域
O(logn)这是一个典型的应用程序用例。Bloom筛选器是一种概率数据结构,针对成员资格测试进行了优化(“X是此集合的成员吗?”),并提供O(1)查找。作为交换,你引入了一个任意小的误报概率——也就是说,过滤器会说一个特定的单词存在,但它实际上不存在。你使用的内存越多,这个概率就越小。然而,错误否定的概率为零:如果一个单词确实存在,过滤器将永远不会说它不存在 在您的特定情况下,使用80亿位(1GB),您可以获得比每100000000次试验中的1略高的假阳性率。这是一个极低的假阳性率。如果你查找了2亿个随机字符串,你从来没有碰到过一个假阳性的概率大约是82% 这不需要对字典进行排序,节省空间,并且不需要数据库或其他辅助存储结构。总的来说,它可能是满足您需求的好选择。假设:
struct chunk {
string word;
int start;
};
chunk index[];
d = index.length / n;
for (i=0;i<n; ++i) {
index[i] = index[i*d];
}
realloc(index, sizeof(chunk) * n);
struct chunk{
字符串字;
int启动;
};
组块索引[];
d=索引长度/n;
对于(i=0;i经典的单词查找问题可以使用一个有效的解决。不幸的是,正如您所提到的,您不能将所有需要的数据存储在内存中,但这不应该阻止您使用Trie来减少搜索空间。假设您不在Trie中存储整个单词集,而是只存储初始段,而您的d节点指向数据库中易于(快速)搜索的小型数据集合。如果某些单词是