String 将算法的大O表示法从O(n^2)改进为更好的形式
我希望改进我目前拥有的一个算法,虽然它有效,但目前的复杂度为O(n^2)。如果可能的话,我希望降低复杂性,或者改进/更改算法本身,以提高运行时间 我有一个字符串列表,每个字符串包含多个单词,最终目标是在这些字符串之间找到“匹配项”,根据“相似性”百分比排序 假设我有以下字符串: “世界末日”String 将算法的大O表示法从O(n^2)改进为更好的形式,string,algorithm,time-complexity,big-o,String,Algorithm,Time Complexity,Big O,我希望改进我目前拥有的一个算法,虽然它有效,但目前的复杂度为O(n^2)。如果可能的话,我希望降低复杂性,或者改进/更改算法本身,以提高运行时间 我有一个字符串列表,每个字符串包含多个单词,最终目标是在这些字符串之间找到“匹配项”,根据“相似性”百分比排序 假设我有以下字符串: “世界末日” “旅程的开始” “时间的终结” “我们今天离开这个世界的时间” 我的算法执行以下步骤: 遍历每个字符串,将每个字符串分解为其组成词,并按字母顺序对这些词重新排序(整个算法不区分大小写)。 (也就是说,“世
“旅程的开始”
“时间的终结”
“我们今天离开这个世界的时间” 我的算法执行以下步骤:
- 遍历每个字符串,将每个字符串分解为其组成词,并按字母顺序对这些词重新排序(整个算法不区分大小写)。 (也就是说,“世界末日”变成了“世界末日”,“我们今天离开这个世界的时候”变成了“今天离开这个世界的时候”等等)
- 出于业务原因,某些单词会从处理过的字符串中删除。这通常是代词和其他类似的词,例如a、the等,所以“世界末日”变成了“世界末日”
- 我们现在有了一个字符串列表,这些字符串被打断,并按照字母顺序从它们的组成词中重新组合,删除了特定的非基本词
- 首先,我可以简单地看看列表中是否有完全相同的副本。这很简单,允许我识别那些实际上是100%匹配的字符串
- 然而,现在是算法中最难和最慢的部分。我必须遍历字符串列表,将每个字符串与列表中的每个其他字符串(即嵌套循环)进行比较,以确定每个字符串在两个被比较字符串中有多少个共同的单词。i、 当比较“世界末日”和“时间末日”时,有66.6%的共性,因为两个字符串有三分之二的共同词。当比较“世界末日”和“Left This Time Today We World”时,我们发现两个字符串之间只有一个单词是相同的(因为每个字符串中的单词数不同,本例中的实际百分比是基于两个字符串之间的平均值计算的,因此大约有22%的共性)
是否有任何方法可以改进该算法的大O,或者对该算法进行任何更改,以产生相同的输出,从而提高运行时的复杂性?如果在所有计算中都使用字符串,则会增加额外的复杂性,这使得最后一个操作不是O(M^2),而是O(M^2*sizeof)(句子)*AvgLength(单词)) 让我们看看(概念代码) 这里的总数是O(sSet.size()^2*O(set.size())。 可以优化为仅运行O(sSet.size()*sSet.size()/2),因为表是对称的 使用
查找
在此处保存因子O(字号)
std::集合可能会被一些平面集合所取代,以实现更快的实际操作。该算法的第一部分的顺序为O(n^2)还有,如果你有N个单词和N行要扫描overNo,就必须将每个句子放入数据结构(如二叉树)中。顺便说一句,你删除的琐碎单词通常称为停止词。通常(但不总是…)在这种情况下,单词越稀罕,就越应该重视一个事实,即它恰好由一对标题共享。在这种情况下,它可以帮助扭转局面,为每个单词记录包含该单词的标题集。然后为每个单词(从出现在最少标题中的单词开始),为每对具有该单词的标题添加一个权重(您可以将这些标题存储在哈希表中)。一旦标题计数开始变得太大,请停止。@meat说整件事是
O(n^2)
对我来说没有多大意义。它是O(M*n*n)
,大致上,其中M
是句子的数量,N
是每个句子中的平均词条数量。但是,正如下文所述,OP已经可以将其归结为O(M*N*lgN)
。如果M
是句子的数量,检查所有句子对就是O(M^2)
操作。我忽略了一个事实,N
在这里指的是术语,而不是句子。
std::vector<std::set<int>> sSets;
sentenceSets.reserve(sentences.size());
for(auto& sentence : sentences) { // O(m)
std::vector<const char *> words = SplitWord(sentence); // O(n) needs to go through all letters.
sSet.emplace_back();
for(auto& word: words) {
int wordNo = LookUp(word); // table of all words, with entries of 0 for unwanted words. O(log AllWords)
if (wordNo)
sSet.back().insert(wordNo); // also removes duplicates. O(Log(#diff words in sentence))
}
}
for(const auto& theSet : sSet) { // O(sSet.size()
for(const auto& cmpSet : sSet) { // O(sSet.size()
std::vector<int> intersect;
std::set_intersection(theSet.begin(), theSet.end(),
cmpSet.begin(), cmpSet.end(),
std::back_insert<std::vector<int>>(intersect)); // O(set.size())
StoreRes(theSet, cmpSet, intersect);
}
}