我正在尝试编写一个算法,告诉我可以使用来自多组值的项生成多少对。例如,我有以下几组: {1,2,3} {4,5} {6}
从这些集合中我可以生成11对: {1,4},{1,5},{1,6},{2,4},{2,5},{2,6},{3,4},{3,5},{3} ,6},{4,6},{5,6}
我写了以下算法:
int result=0;
for(int k=0;k<numberOfSets;k++){ //map is a list where I store all my sets
int size1 = map.get(k);
for(int l=k+1;l<numberOfSets;l++){
int size2 = map.get(l);
result += size1*size2;
}
}
但是你可以看到算法的可扩展性不是很高。如果集合的数量增加,则算法开始执行得非常差。 我错过了什么吗?有没有一种算法可以帮我解决这个问题?我一直在寻找组合和置换算法,但我不太确定这是不是正确的道路。
非常感谢您提前
答案 0 :(得分:1)
首先,如果配对中的顺序确实重要,那么在内循环中以int l=k+1
开头是错误的。例如。如果您认为{4,1}
与{1,4}
相同,那么您将失踪{1,2} , {2,3}, {4}
,那么结果是正确的,否则它就不是。
其次,为了使问题进一步复杂化,你不能说这些对是否必须是唯一的。例如。 {2,4}
将生成Set<Pair<int,int>>
两次 - 如果您需要将其计为唯一,则代码的结果不正确(并且您需要保留use Firebase\JWT\JWT;
以删除重复项和您将需要扫描这些集并实际生成对)。
好消息:虽然你不能比O(N 2 )更好地计算对,即使你有数千套,数百万的整数乘法/加法在现在的计算机上足够快 - 例如Eigen deals quite well with O(N^3) operations用于浮动乘法(参见矩阵乘法运算)。
答案 1 :(得分:0)
假设你只关心对的数量,并且正在计算重复数,那么有一个更有效的算法:
我们将跟踪当前的集合数量,以及到目前为止遇到的元素数量。
代码:
int numberOfPairs=0;
int elementsEncountered=0;
for(int k = numberOfSets - 1 ; k >= 0 ; k--) {
int sizeOfCurrentSet = map.get(k);
int numberOfNewPairs = sizeOfCurrentSet * elementsEncountered;
numberOfPairs += numberOfNewPairs;
elementsEncountered += sizeOfCurrentSet;
}
重新定位的关键点在于,当我们计算每个集合所贡献的新对的数量时,我们选择该对的第二个元素与哪个集合无关紧要。也就是说,我们不需要跟踪我们已经分析过的任何集合。