簡體   English   中英

向量的交集

[英]Intersection of vectors

我的向量很少。 例如 4

std::vector1 <CMyClass>;
std::vector2 <CMyClass>;
std::vector3 <CMyClass>;
std::vector4 <CMyClass>;

我想要一個結果向量,它將具有存在於所有向量中的對象。 例如。 如果

Vector1 has C1, C2, C3;
Vector2 has C1, C2;
Vector3 has C1, C4;
Vector has  C1, C5;

我希望結果向量具有 C1。

我可以運行循環並比較並找出結果向量,但我想知道是否有任何直接的方法可以做到這一點。 像一些運算符或數據結構。

  1. 對向量進行排序。
  2. 使用std::set_intersection()三次(與您擁有的向量一樣多 - 1)。

時間復雜度分析:

  • 4 * O(nlogn) = O(nlogn)
  • 線性 2 * (firstSize + secondSize) - 1
  • 線性 2 * (firstSecondInterSize +thirdSize) - 1
  • 線性 2 * (firstSecondThirdInterSize + FourSize) - 1

它以 O(nlogn) 為界,這意味着排序是算法的瓶頸。


完整代碼示例:

#include <iostream>     // std::cout
#include <algorithm>    // std::set_intersection, std::sort
#include <vector>       // std::vector

int main () {
  std::vector<int> first = {5,10,15,20,25};
  std::vector<int> second = {50,40,30,20,10};
  std::vector<int> third = {10,20,3,4,0};
  std::vector<int> fourth = {4,20,10,3,6};
  std::vector<int> v(first.size() + second.size() + third.size() + fourth.size());
  std::vector<int>::iterator it;

  std::sort (first.begin(),first.end());
  std::sort (second.begin(),second.end());
  std::sort (third.begin(),third.end());
  std::sort (fourth.begin(),fourth.end());

  it=std::set_intersection (first.begin(), first.end(), second.begin(), second.end(), v.begin());
  it=std::set_intersection (v.begin(), v.end(), third.begin(), third.end(), v.begin());
  it=std::set_intersection (v.begin(), v.end(), fourth.begin(), fourth.end(), v.begin());
  v.resize(it-v.begin());

  std::cout << "The intersection has " << (v.size()) << " elements: ";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

輸出:

交集有 2 個元素:10 20

這是一個交集,而不是超集(這意味着四個向量中任何一個中包含的所有元素的聯合或集合)。

如果可以對向量進行排序,直接的方法是使用std::set_intersection

您必須使用它 3 次,獲得中間結果A=intersection(v1,v2)B=intersection(3,4) ,然后才能從cross(A,B)獲得最終結果。

使用這個鏈接的答案會更有效(跳過兩個中間容器),但確實需要更多的手動編碼(和測試)。

這個怎么辦? 您必須在類中添加 operator<()(和輔助運算符<<())。 從每個向量形成 std​​::set,然后計算這些集合的交集。 再次 - 從結果集制作向量。

#include <iostream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <set>

class CMyClass
 {
 public:
     CMyClass(int n){_n=n;}
     ~CMyClass(){}
     bool operator<(const CMyClass a) const{return _n <a._n;}
     friend std::ostream& operator<<(std::ostream& s,const CMyClass& a){s<<a._n;return s;}
 private:
     int _n;
 };
vector<CMyClass> find_intersect(vector<vector<CMyClass>>& vecs)
{
    vector<CMyClass> res;
    if (vecs.empty()) return res;
    set<CMyClass> S;
    for_each(vecs[0].begin(),vecs[0].end(),[&S](const CMyClass& e){S.insert(e);});
    for(auto &vec:vecs)
    {
        set<CMyClass> s,tmp;
        for_each(vec.begin(),vec.end(),[&s](const CMyClass& e){s.insert(e);});
        set_intersection(S.begin(),S.end(),s.begin(),s.end(),std::inserter(tmp,tmp.begin()));
        S=tmp;
        if (S.empty()) break;
    }
    for_each(S.begin(),S.end(),[&res](const CMyClass& e){res.push_back(e);});
    return res;
}

int main()
{
    vector<CMyClass> v1={1,2,3};
    vector<CMyClass> v2={1,2};
    vector<CMyClass> v3={1,4};
    vector<CMyClass> v4={1,5};
    vector<vector<CMyClass>> vectors;
    vectors.push_back(v1);
    vectors.push_back(v2);
    vectors.push_back(v3);
    vectors.push_back(v4);
    auto res = find_intersect(vectors);
    cout<<"[";
    for(auto &elem:res)
        cout<<elem<<",";
    cout<<"]"<<endl;
}

輸出:[1,]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM