📜  n 个集合的交集

📅  最后修改于: 2022-05-13 01:57:13.677000             🧑  作者: Mango

n 个集合的交集

给定 n 组不同大小的整数。每个集合也可能包含重复项。如何找到所有集合的交集。如果一个元素在所有集合中多次出现,则应该在结果中多次添加。

例如,考虑有三个集合 {1,2,2,3,4} {2,2,3,5,6} {1,3,2,2,6}。给定集合的交集应该是 {2,2,3}

以下是解决此问题的有效方法。

1.对所有集合进行排序。
2.取最小的集合,将所有元素及其频率插入到映射中。
3.对地图中的每个元素执行以下操作
... ..一。如果该元素不存在于任何集合中,则忽略它
...。B。查找每个集合中元素的频率(使用二进制搜索)。如果它小于地图中的频率,则更新频率
... ..℃。如果在所有集合中都找到该元素,则将其添加到结果中。

这是上述方法的 C++ 实现。



// C++ program to find intersection of n sets
#include 
#include 
#include 
#include 
using namespace std;
  
// The main function that receives a set of sets as parameter and
// returns a set containing intersection of all sets
vector  getIntersection(vector < vector  > &sets)
{
    vector  result;  // To store the reaultant set
    int smallSetInd = 0;  // Initialize index of smallest set
    int minSize = sets[0].size(); // Initialize size of smallest set
  
    // sort all the sets, and also find the smallest set
    for (int i = 1 ; i < sets.size() ; i++)
    {
        // sort this set
        sort(sets[i].begin(), sets[i].end());
  
        // update minSize, if needed
        if (minSize > sets[i].size())
        {
            minSize = sets[i].size();
            smallSetInd = i;
        }
    }
  
    map elementsMap;
  
    // Add all the elements of smallest set to a map, if already present,
    // update the frequency
    for (int i = 0; i < sets[smallSetInd].size(); i++)
    {
        if (elementsMap.find( sets[smallSetInd][i] ) == elementsMap.end())
            elementsMap[ sets[smallSetInd][i] ] = 1;
        else
            elementsMap[ sets[smallSetInd][i] ]++;
    }
  
    // iterate through the map elements to see if they are present in
    // remaining sets
    map::iterator it;
    for (it = elementsMap.begin(); it != elementsMap.end(); ++it)
    {
        int elem = it->first;
        int freq = it->second;
  
        bool bFound = true;
  
        // Iterate through all sets
        for (int j = 0 ; j < sets.size() ; j++)
        {
            // If this set is not the smallest set, then do binary search in it
            if (j != smallSetInd)
            {
                // If the element is found in this set, then find its frequency
                if (binary_search( sets[j].begin(), sets[j].end(), elem ))
                {
                   int lInd = lower_bound(sets[j].begin(), sets[j].end(), elem)
                                                            - sets[j].begin();
                   int rInd = upper_bound(sets[j].begin(), sets[j].end(), elem)
                                                            - sets[j].begin();
  
                   // Update the minimum frequency, if needed
                   if ((rInd - lInd) < freq)
                       freq = rInd - lInd;
                }
                // If the element is not present in any set, then no need 
                // to proceed for this element.
                else
                {
                    bFound = false;
                    break;
                }
            }
        }
  
        // If element was found in all sets, then add it to result 'freq' times
        if (bFound)
        {
            for (int k = 0; k < freq; k++)
                result.push_back(elem);
        }
    }
    return result;
}
  
// A utility function to print a set of elements
void printset(vector  set)
{
    for (int i = 0 ; i < set.size() ; i++)
        cout< > sets;
    vector  set1;
    set1.push_back(1);
    set1.push_back(1);
    set1.push_back(2);
    set1.push_back(2);
    set1.push_back(5);
  
    sets.push_back(set1);
  
    vector  set2;
    set2.push_back(1);
    set2.push_back(1);
    set2.push_back(4);
    set2.push_back(3);
    set2.push_back(5);
    set2.push_back(9);
  
    sets.push_back(set2);
  
    vector  set3;
    set3.push_back(1);
    set3.push_back(1);
    set3.push_back(2);
    set3.push_back(3);
    set3.push_back(5);
    set3.push_back(6);
  
    sets.push_back(set3);
  
    vector  r = getIntersection(sets);
  
    printset(r);
  
}
  
// Driver program to test above functions
int main()
{
    TestCase1();
    return 0;
}

输出:

1 1 5

时间复杂度:假设有“n”个列表,列表的平均大小为“m”。排序阶段需要 O( n* m *log m) 时间(排序 n 个平均长度为 m 的列表)。搜索阶段需要 O( m * n * log m) 时间。 (对于列表中的每个元素,我们用 log m 时间搜索 n 个列表)。所以总的时间复杂度是 O( n*m*log m )。

辅助空间:用于存储地图的 O(m) 空间。