ハッシュテーブルを使用して異なるセットを表すことができます。この方法では、交差全体を計算することはO(M)です。ここで、Mはすべてのセットの要素の合計数です。
次に、元のセットと計算された交差点との間の差異を計算する必要があります。ここでもまた、ハッシュテーブルを使用して、これは実際に高速で行われます。O(K * N)ここで、Kは全体交差の要素の数です。Nセットの数。
アルゴリズムの構造は、ネストされていない2つのforループを使用します。最初のすべてのセットの交差を計算する、2番目のすべてのセットで冗長な要素を取り除く。
C++の実行例は、Coliruにあります。
#include <vector>
#include <iostream>
#include <algorithm>
#include <unordered_set>
// Complexity: O(min(set1.size(), set2.size()))
template <typename T>
std::unordered_set<T> intersection(std::unordered_set<T> const& set1, std::unordered_set<T> const& set2) {
if (set2.size() < set1.size()) {
return intersection(set2, set1);
} else {
std::unordered_set<T> inter;
for (auto const& el1 : set1) {
if (std::find(set2.cbegin(), set2.cend(), el1) != set2.cend()) {
inter.emplace(el1);
}
}
return inter;
}
}
using int_hashset = std::unordered_set<int>;
int main()
{
std::vector<int_hashset> input_sets = {{1, 2, 3, 4, 5},
{3, 4, 5, 6, 7, 8},
{3, 5, 6, 7, 8}};
auto inter_set = *input_sets.cbegin();
// Complexity: O(number of elements)
for (auto it = input_sets.cbegin()+1; input_sets.cend() != it; ++it) {
inter_set = intersection(inter_set, *it);
}
for (auto const& i : inter_set) {
std::cout << "Elem in overall intersection: " << i << '\n';
}
// O(N*inter_set.size())
for (auto& input_set : input_sets) {
// O(inter_set.size())
for (auto el : inter_set) {
input_set.erase(el);
}
}
int i = 0;
for (auto const& input_set : input_sets) {
++i;
for (auto el : input_set) {
std::cout << "Element in set " << i << ": " << el << '\n';
}
}
return 0;
}
注:これは償却された複雑さです。あなたのセットの中にたくさんの衝突があると複雑さが増します。
すぐにお返事ありがとうございます。いくつかのサンプルコードを共有できますか?私の混乱は、単一のループですべてのセットの交差を見つけることです。 – user1879599
@ user1879599もちろん、あなたの質問は言語にとらわれません...どの言語を使うべきですか? – Rerito
C#を推奨しますが、Javaも問題ありません。 – user1879599