C++ 向量差异

C++ 向量差异,c++,std,C++,Std,如何确定两个向量的差异 我有向量v1和向量v2 我要找的是一个向量vDifferences,它只包含v1或v2中的元素 是否有一种标准的方法来执行此操作?是否希望中的v1和v2中的元素都是唯一的且不在其他序列中?听起来像是 复制范围[first1,last1]中不存在的元素 在范围[first2,last2]中,以及该范围的元素 [first2,last2]不在[first1,last1]到范围内 从结果开始的范围。构造范围中的元素 它们被分类了 以下是完整且正确的答案。在使用set\u sym

如何确定两个向量的差异

我有
向量v1
向量v2

我要找的是一个
向量vDifferences
,它只包含
v1
v2
中的元素


是否有一种标准的方法来执行此操作?

是否希望中的
v1
v2
中的元素都是唯一的且不在其他序列中?听起来像是

复制范围[first1,last1]中不存在的元素 在范围[first2,last2]中,以及该范围的元素 [first2,last2]不在[first1,last1]到范围内 从结果开始的范围。构造范围中的元素 它们被分类了


以下是完整且正确的答案。在使用
set\u symmetric\u difference
算法之前,必须对源范围进行排序:

  using namespace std; // For brevity, don't do this in your own code...

  vector<int> v1;
  vector<int> v2;

  // ... Populate v1 and v2

  // For the set_symmetric_difference algorithm to work, 
  // the source ranges must be ordered!    
  vector<int> sortedV1(v1);
  vector<int> sortedV2(v2);

  sort(sortedV1.begin(),sortedV1.end());
  sort(sortedV2.begin(),sortedV2.end());

  // Now that we have sorted ranges (i.e., containers), find the differences    
  vector<int> vDifferences;

  set_symmetric_difference(
    sortedV1.begin(),
    sortedV1.end(),
    sortedV2.begin(),
    sortedV2.end(),
    back_inserter(vDifferences));

  // ... do something with the differences
为了确定哪种解决方案更适合特定情况,分析这两种算法将是明智的做法。尽管基于哈希表的解决方案处于O(n)状态,但它需要更多的代码,并且每发现一个重复项(即,哈希表删除)就要做更多的工作。这也(很遗憾)使用自定义差分函数而不是标准STL算法

应该注意的是,这两种解决方案所呈现的差异顺序很可能与元素在原始容器中出现的顺序完全不同。有一种方法可以通过使用哈希表解决方案的变体来解决这一问题。下面是一个高级描述(仅在步骤4中与前面的解决方案不同):

  • 将每个容器加载到哈希表中
  • 如果两个容器大小不同,则在步骤3中使用较小的哈希表进行遍历。否则,将使用两个容器中的第一个
  • 遍历在步骤2中选择的哈希表,检查两个哈希表中是否都存在每个项。如果存在,则将其从两个哈希表中删除
  • 要形成差异容器,请按顺序遍历原始容器(即,第一个容器先于第二个容器)。在其各自的哈希表中查找每个容器中的每个项。如果找到,则将该项添加到差异容器并从其哈希表中删除。将跳过各个哈希表中不存在的项。因此,只有哈希表中存在的项才会进入差异容器及其顺序外观的顺序将保持与原始容器中相同,因为这些容器规定了最终遍历的顺序
  • 为了维持原始订单,步骤4比以前的解决方案成本更高,尤其是在移除的项目数量较多的情况下。这是因为:

  • 所有项目都将通过其各自哈希表中的存在性测试,第二次测试是否有资格显示在差异容器中
  • 当差异容器形成时,哈希表的剩余项将一次删除一个,作为项目1差异测试的一部分

  • 我认为你正在寻找的是如果改变<代码> V1 < /C> >代码> V2是一个选项,你只关心每个元素是否在其中,考虑使用<代码> STD::unOrdEdEdSt< <代码>或<代码> STD::设置而不是<代码> STD::vector < /代码>。
    using namespace std; // For brevity, don't do this in your own code...
    
    // The remove_common_items function template removes some and / or all of the
    // items that appear in both of the multisets that are passed to it. It uses the
    // items in the first multiset as the criteria for the multi-presence test.
    template <typename tVal>
    void remove_common_items(unordered_multiset<tVal> &ms1, 
                             unordered_multiset<tVal> &ms2)
    {
      // Go through the first hash table
      for (auto cims1=ms1.cbegin();cims1!=ms1.cend();)
      {
        // Find the current item in the second hash table
        auto cims2=ms2.find(*cims1);
    
        // Is it present?
        if (cims2!=ms2.end())
        {
          // If so, remove it from both hash tables
          cims1=ms1.erase(cims1);
          ms2.erase(cims2);
        }
        else // If not
          ++cims1; // Move on to the next item
      }
    }
    
    int main()
    {
      vector<int> v1;
      vector<int> v2;
    
      // ... Populate v1 and v2
    
      // Create two hash tables that contain the values
      // from their respective initial containers    
      unordered_multiset<int> ms1(v1.begin(),v1.end());
      unordered_multiset<int> ms2(v2.begin(),v2.end());
    
      // Remove common items from both containers based on the smallest
      if (v1.size()<=v2.size)
        remove_common_items(ms1,ms2);
      else
        remove_common_items(ms2,ms1);
    
      // Create a vector of the union of the remaining items
      vector<int> vDifferences(ms1.begin(),ms1.end());
    
      vDifferences.insert(vDifferences.end(),ms2.begin(),ms2.end());
    
      // ... do something with the differences
    }