如何删除2套之间不相关的元素?与SQL join类似

时间:2013-02-22 08:16:49

标签: algorithm join inner-join

假设我有两组,如:

A = { 1, 4, 7, 10, 11, 12 }
B = { a, b, x, y, z }

我有一个函数可以确定A中的元素是否与B中的另一个元素相关:

bool isRelated(a, b)

我想从A和B中删除没有任何相关元素的元素。我怎样才能做到这一点?一个简单的方法是:

forEach a in A:
    related = 0
    forEach b in B:
        if isRelated(a, b):
            related++
            break
    if related == 0 
        A.remove(a)

// then I need to do something similar for B

对我来说效率很低。有没有更好的办法?肯定有更好的办法?

2 个答案:

答案 0 :(得分:0)

这在时间复杂度上非常相似,但由于linq的懒惰,它可以为你节省一些。

这是一个C#示例:

var newA = A.Where(a=> B.Any(b=> IsRelated(a,b)).Select(a); //checks the desired condition
var newB = B.Where(b=> A.Any(a=> IsRelated(a,b)).Select(b);
A = newA;
B = newB'

答案 1 :(得分:0)

一般来说,没有更好的方法。 SQL数据库在识别join子句中的特定条件时进行优化,他们可以使用索引(已经存在的索引或动态构建的数据结构)来查找所有匹配而不扫描整个集合。并非所有可能的关系都与任何索引有关。

您可以在B的所有元素的第一个循环中保留记录,isRelated返回true。然后在尚未编写的第二个循环中,您可以在循环(现在简化的)集合A之前检查缓存。一旦这个到位,也许你可以(在第一个循环中)不总是从头开始搜索B,以便为后面的B元素提供更好的机会进入缓存。 / p>

除此之外,我认为这里没有任何大的节省。