假设我有两组,如:
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
对我来说效率很低。有没有更好的办法?肯定有更好的办法?
答案 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>
除此之外,我认为这里没有任何大的节省。