作为搜索引擎的一部分,我开发了倒排索引。
所以我有一个包含以下类型元素的列表
public struct ForwardBarrelRecord
{
public string DocId;
public int hits { get; set; }
public List<int> hitLocation;
}
现在这条记录只针对一个单词。 hitLocation包含在文档中找到特定单词的位置。
现在我想要的是计算List<int> hitLocation
中元素与另一个List<int> hitLocation
的接近程度,然后如果列表中的元素相邻,则增加两个记录的权重。
我遇到的问题是为此找到合适的算法。感谢任何帮助
答案 0 :(得分:1)
如果hitLocation
列表按排序顺序,这是最简单的。所以从:
var word1List = word1.hitLocation.Orderby(s => s).ToList();
var word2List = word2.hitLocation.Orderby(s => s).ToList();
虽然如果您为搜索引擎执行此操作,那么您可能希望这些列表在倒排索引中进行预先排序。
无论如何,一旦你对列表进行了排序,找到匹配就很容易了。
int ix1 = 0;
int ix2 = 0;
while (ix1 < word1List.Count && ix2 < word2List.Count)
{
int hit1 = word1List[ix1];
int hit2 = word2List[ix2];
if (hit1 < hit2)
{
if ((hit2 - hit1) == 1)
{
Console.WriteLine("Match at {0} and {1}", hit1, hit2);
}
ix1++;
}
else
{
ix2++;
}
}
这将找到word1后跟word2的出现次数。如果你还想要word2后跟word1,你可以在else
子句中进行类似的检查。
答案 1 :(得分:0)
#include <iostream>
#include <list>
#include <string>
using namespace std;
struct ForwardBarrelRecord
{
string DocId;
int hits;
list<int> hitLocation;
};
void merge(struct ForwardBarrelRecord& fa, struct ForwardBarrelRecord& fb)
{
list<int>& la = fa.hitLocation;
list<int>& lb = fb.hitLocation;
la.sort();
lb.sort();
std::list<int>::iterator ita = la.begin();
std::list<int>::iterator itb = lb.begin();
while(ita != la.end() && itb != lb.end())
{
int loc_a = *ita;
int loc_b = *itb;
if (loc_a < loc_b)
{
if (loc_a + 1 == loc_b)
{
cout << "adjacent pair (" << loc_a << ", " << loc_b << ")" << endl;
}
ita++;
}
else if (loc_a > loc_b)
{
if (loc_b + 1 == loc_a)
{
cout << "adjacent pair (" << loc_a << ", " << loc_b << ")" << endl;
}
itb++;
}
else
{
ita++;
itb++;
if (ita != la.end() && *ita == loc_b + 1)
{
cout << "adjacent pair (" << *ita << ", " << loc_b << ")" << endl;
}
if (itb != lb.end() && *itb == loc_a + 1)
{
cout << "adjacent pair (" << loc_a << ", " << *itb << ")" << endl;
}
}
}
}
int main() {
struct ForwardBarrelRecord fa;
fa.hitLocation.push_back(1);
fa.hitLocation.push_back(2);
fa.hitLocation.push_back(3);
struct ForwardBarrelRecord fb;
fb.hitLocation.push_back(2);
fb.hitLocation.push_back(3);
merge(fa, fb);
return 0;
}
请参阅代码,在2个排序列表的合并扫描中输出所有相邻的命中位置。