【问题标题】:Intersection of vectors向量的交集
【发布时间】:2017-10-13 16:08:16
【问题描述】:

我的向量很少。例如 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。

我可以运行循环并比较并找出结果向量,但我想知道是否有任何直接的方法可以做到这一点。 像一些运算符或数据结构。

【问题讨论】:

标签: c++ algorithm vector data-structures intersection


【解决方案1】:
  1. 对向量进行排序。
  2. 使用std::set_intersection() 3 次(与您拥有的向量一样多 - 1)。

时间复杂度分析:

  • 4 * O(nlogn) = O(nlogn)
  • 线性为 2 * (firstSize + secondSize) - 1
  • 线性在 2 * (firstSecondInterSize + thirdSize) - 1
  • 线性 2 * (firstSecondThirdInterSize + FourthSize) - 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

【讨论】:

    【解决方案2】:

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

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

    您必须使用它 3 次,获得中间结果 A=intersection(v1,v2)B=intersection(3,4),然后才能获得intersection(A,B)的最终结果。

    使用这个linked answer 会更高效(跳过两个中间容器),但确实需要更多的手动编码(和测试)。

    【讨论】:

      【解决方案3】:

      这个呢?你必须在你的类中添加 operator

      #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,]

      【讨论】:

        猜你喜欢
        • 2015-08-06
        • 2013-10-29
        • 1970-01-01
        • 1970-01-01
        • 2015-09-12
        • 1970-01-01
        • 2018-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多