【问题标题】:how to perform efficient sets intersection operation?如何执行高效的集合交集操作?
【发布时间】:2012-02-17 17:22:42
【问题描述】:

我得到了称为 tokens 的元素。它们中的每一个都是某种关联容器(不一定是 std 容器之一)。我得到了某种类型的容器 storage 来存储令牌(不一定是 std 容器之一)。存储是一组 令牌
我需要能够通过具有指定比较器的指定键对 token 值上的令牌集(storage)执行交集操作。 作为该操作的结果,我想获得另一组令牌(另一个 storage)。

伪代码用例:

  if ( (storage0[key1]==storage1[key1])[key2]<storage1[key2] )
    ...

我正在寻找一种有效的算法来做到这一点。
注意:我得到了几十个令牌
问题:
1)如何组织存储
2)如何实现路口操作?

更新一些解释:
token 是一组(键,值)对。 storage 是一组 (key,value) 对的集合

我需要相交(P1,K1,P2,K2,cmp)
P1 - 第一个存储
P2 - 第二存储
K1 - 第一次存储的密钥
K2 - 第二个存储的密钥
cmp - 比较函数,如 cmp(value,value),返回 true 或 false

Intersect 应该经过 P1 的每个元素 e1,并且经过 P2 的每个元素 e2 并提取满足 cmp(e1[K1],e2[K2]) 的那些元素((键,值)对)

【问题讨论】:

  • 看了几遍还是理解有问题:(是不是这样:token是一组(key,value)对。存储是一组(key,value)对. 你需要intersect(P,q,cmp), 其中P-storage, q-token, cmp - 两个(key,value) 对之间的比较函数。Intersect 应该遍历P 的每个元素e,并提取那些(key,value ) 对满足cmpq 的任何元素?
  • 这段代码:if ( (storage0[key1]==storage1[key1])[key2]
  • @fjardon if (((storage0[key1]==storage1[key1])[key2]
  • (storage0[key1]==storage1[key1]) 是一个布尔值。那么 (storage0[key1]==storage1[key1])[key2] 是什么?
  • 大多数看到== 的人认为它是一个返回truefalse 的二元运算符。您是否正在做一些返回一组布尔值的集合范围比较?还是 lambda 演算?另外,首先storage[key] 是什么?我认为 storage 只是一个集合,而不是一些 (key,set) 映射。用于存储的key 和相同类型的令牌元素的键是否相同?它们有什么关系?

标签: c++ algorithm


【解决方案1】:

Inverted index 有效地处理交集,所以你可以做类似的事情。

这个想法是:每个集合实际上都是一个列表,带有一个高效的getFirstAfter(key) 函数——它返回key 之后的第一个标记。对于每个集合 - 您需要检查相关元素是否在其中 - 如果没有 - 前进到集合中的下一个元素。

(*) 请注意,此算法中枚举了令牌

(*)假设 T 包含您想要相交的所有列表[算法有效地相交超过两个列表]

伪代码:

lastTok <- 0 //the first token in the collection
currSet <- 0 //the first set 
while (lastTok != infinity):
  if (currSet > T.last): //if we have passed the last set
     insert lastTok into result
     currSet <- 0
     lastTok <- lastTok + 1
     continue
  currentToken<- T[currSet].getFirstAfter(lastTok-1)
  if (currentToken!= lastTok):
     lastTok<- currentToken
     currSet <- 0
  else: 
     currSet <- currSet + 1

该算法假设有效的getFirstAfter() 可以为您提供第一个适合该术语的文档,并且他的 docId 大于指定的参数。如果没有,它应该返回无穷大。

如果对术语进行排序以使最稀有的术语在前,则该算法将是最有效的。

该算法最多可确保#docs_matching_first_term * #terms 次迭代,但实际上 - 通常迭代次数会少得多。

更多信息可以在this lecture notes slides 11-13 [版权在讲座的第一页]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    相关资源
    最近更新 更多