选择前缀数量最多的索引

Select the index which has the most number of prefixes among others?

本文关键字:索引 前缀 选择      更新时间:2023-10-16

我有很多0和1的序列,我想找到一个具有最大数量的其他序列的序列,这些序列构成当前序列的前缀。

示例:

std::vector<std::vector<int>> sequence={{1,1},{1},{0,1,0,1},{1,1,0}}

{1,1}只有1个前缀,即{1}。

但是{1,1,0}有两个前缀{1,1}和{1}。由于它有最多的前缀计数,我想选择sequence.的索引3。我可以用嵌套循环来完成它,但它消耗了很多时间,因为我必须处理大小512的序列。谢谢你的帮助。

到目前为止我所做的:

bool isPrefixOf(std::vector<int> current, std::vector<int> other){
if (other.size()>current.size())
return false;
for (int i=0; i<other.size(); ++i) {
if (other[i] != current[i]) 
return false;
}
return true; 
}
int len = sequence.size();
int max = 0;
int selected = -1;
int prefix_count;
for(int i=0; i<len; i++){
prefix_count = 0;
for(int j=0; j<len; j++){
if(isPrefixOf(sequence[i],sequence[j])) ++prefix_count;
}
if(prefix_count >= max){
max = prefix_count;
selected = i;
}
}

您的双循环会产生O(n2(算法。如果你构建一个前缀树(在你的情况下是二进制的(,你可以得到一个O(n(,如下所示:

  • 对于每个序列,迭代值,在0上跟随左子项,在1上跟随右子项。创建新的子项(如果不存在(
  • 如果序列结束,则递增当前节点(无论是否为叶!(。变量:如果不想计算重复项,只需将节点值设置为1(无论以前是否如此(
  • 感兴趣的只是叶子,因为任何父节点都与叶子共享前缀,但它本身就是一个前缀,所以叶子(至少(还有一个前缀
  • 对于每片叶子,将从根到叶子的路径上的值相加
  • 具有最大值的叶子标记您所追求的序列;在计算和的时候,你可以记住最大右边,这样你就不必在树上走两次了

对于给定的示例,树看起来像这样:

[0] (root, always 0)
/   
/(0)  (1)
/       
[0]       [1] (one sequence finished here!)
         
(1)      (1)
         
[0]       [1]
/          /
/(0)       /(0)
/          / 
[0]        [1]<3>

(1)

[1]<1>

将叶子包括在总和中将正确地考虑叶子中的重复项。这将包括形成叶子本身路径的序列(解释:每个序列都是自己的前缀(,但由于每个叶子都是这样,所以所有叶子的偏移量都相等,所以这对最大值没有影响,你追求的是。。。

您可以在节点内额外存储指向节点的序列索引,以便在原始向量中更快地访问。