快速高效的数组计算

Posted

技术标签:

【中文标题】快速高效的数组计算【英文标题】:Fast and efficient computation on arrays 【发布时间】:2012-12-05 03:36:48 【问题描述】:

我想计算文档中特定短语的出现次数。例如“*** 论坛”。假设 D 表示文档集,其中包含两个词条的文档。

现在,假设我有以下数据结构:

A[numTerms][numMatchedDocuments][numOccurInADocument] 

其中 numMatchedDocuments 是 D 的大小,numOccurInADocument 是特定术语在特定文档中出现的次数,例如:

A[***][document1][occurance1]=3;

意味着,术语“***”出现在文档“document1”中,它的第一次出现在位置“3”。

然后我选择出现最少的术语并遍历其所有位置以查找“论坛”是否出现在当前术语“***”位置的位置+1。换句话说,如果我在位置 4 找到“论坛”,那么这是一个短语,我已经找到了一个匹配项。

每个文档的匹配很简单,运行速度相当快,但是当文档数量超过 2,000,000 时,它会变得非常慢。我已经将它分布在核心上,它当然会变得更快,但想知道是否有算法上更好的方法来做到这一点。

谢谢,

伪代码:

boolean docPhrase=true;
int numOfTerms=2;
// 0 for "***" and 1 for "forums"
for (int d=0;d<D.size();d++)
 //D is a set containing the matched documents
 int minId=getTheLeastOccuringTerm();
 for (int i=0; i<A[minId][d].length;i++) // For every position for LeastOccuringTerm
   for( int t=0;t<numOfTerms;t++) // For every terms
      int id=BinarySearch(A[t][d], A[minId][d][i] - minId + t);
      if (id<0) docPhrase=false;
   
 

【问题讨论】:

也许将您当前的实现发布在代码中仅供参考。 @MelNicholson ...但想知道是否有算法上更好的方法来做到这一点。 您需要预先存储所有这些吗?或者您可以实时填充结构(例如,当人们搜索时)? @sdasdadas 我不确定“商店”是什么意思。数组不是存储的,而是从索引中获取的,而且速度很快,没有问题。计数是。 听起来像是 Suffix Arrays 解决的问题。 en.wikipedia.org/wiki/Suffix_array 这个回答我对一个稍微不同的问题给出了一个简单的后缀数组实现:***.com/questions/10606728/… 在 SO 和网络上有相当多的实现。 【参考方案1】:

正如我在 cmets 中提到的,Suffix Array 可以解决此类问题。我用后缀数组的简单 c# 实现回答了类似的问题 (Fastest way to search a list of names in C#)。

基本思想是你有一个索引对数组,它们指向一个文档索引,以及该文档中的一个位置。索引对表示从文档中的该点开始并一直到文档末尾的字符串。但实际文档及其内容仅在您的原始存储中存在一次。后缀数组只是这些索引对的数组,每个文档中的每个位置都有一对。然后按照它们指向的文本的顺序对 Suffix Array 进行排序。排序后,您现在可以通过对 Suffix Array 进行简单的二分搜索,非常快速地在任何文档中找到任何短语。构建(主要是排序)后缀数组可能很耗时。但是一旦构建,搜索速度非常快。由于实际文档内容只存在一次,因此在内存上相当容易。

将其扩展到返回每个文档中的短语匹配计数是微不足道的。

这与 Suffix Array 的经典描述略有不同,他们通常谈论 Suffix Array 在单个非常大的字符串上运行。但是使其适用于字符串/文档数组的更改并没有那么大,尽管它可以增加 Suffix Array 消耗的内存量,具体取决于最大文档数和最大文档长度,以及您如何编码索引对。

【讨论】:

以上是关于快速高效的数组计算的主要内容,如果未能解决你的问题,请参考以下文章

使用jQuery快速高效制作网页交互特效

使用 CuPy 或 NumPy 高效计算分区总和

如何高效快速的学习大数据

Python数据分析-Numpy

快速排序(java)

Matlab编程Matlab高效编程技巧