C++ - 将一个向量附加到另一个向量,并删除重复项

C++ - Appending one Vector to another, with removal of duplicates?

本文关键字:向量 另一个 删除 一个 C++      更新时间:2023-10-16

我想将一个向量(vectorAlpha)附加到另一个向量(vectorBeta)的末尾。我能想到两种不同的方法,我想知道如何做每种方法。

第一种方法是附加第二个向量并从新向量中删除所有重复项。另一种方法是在单个向量中保留重复项,但如果它们已经存在于vectorALpha中,则不从vectorBeta添加任何项目。

例如,如果向量是具有以下值的向量:

矢量阿尔法:

First line of alpha
An alpha line
An alpha line
Some line
Alpha fifth line

矢量测试版:

Beta first line
A beta line
A beta line
Some line
Beta fifth line

我认为第一种方法将导致组合向量:

First line of alpha
An alpha line
Some line
Alpha fifth line
Beta first line
A beta line
Beta fifth line

虽然第二种方法只是将两个数组组合在一起,但未添加第二个向量的"某行":

First line of alpha
An alpha line
An alpha line
Some line
Alpha fifth line
Beta first line
A beta line
A beta line
Beta fifth line
用于

这两个应用C++代码是什么?

因为很明显

  1. 您只希望重复项从 vecB 中删除条目(如果它们存在于 vecA 中),而不是一般的重复项
  2. 您想要保留订单

答案应该是(显然?)是std::remove_copy_if。这样称呼它:

#include <vector>
#include <algorithm>
typedef std::vector<int> Vec;
struct Contained
{
    const Vec& _sequence;
    Contained(const Vec &vec) : _sequence(vec) {}
    bool operator()(int i) const 
    { 
        return _sequence.end() != std::find(_sequence.begin(), _sequence.end(), i);
    }
};
int main()
{
    Vec vecA;
    Vec vecB;
    std::remove_copy_if(vecB.begin(), vecB.end(), back_inserter(vecA), Contained(vecA));
}

您可能希望根据 vecA 的大小和性质优化谓词:

#include <set>
template <typename T>
struct Contained
{
    const std::set<T> _set;
    template <typename It> Contained(const It& begin, const It& end) : _set(begin, end) {}
    bool operator()(const T& i) const 
    { 
        return _set.end() != _set.find(i);
    }
};

这将用作Contained<int>(vecA.begin(), vecA.end()).完整代码正在编译 codepad.org

干杯

更新:由于更改/添加的要求,此处的新答案

typedef std::...<...> Vec;
Vec vecA;
Vec vecB;
// fill your data
// sort
std::sort(vecA.begin(), vecA.end());
std::sort(vecB.begin(), vecB.end());

// join
size_t mergesize = vecA.size();
std::copy(vecB.begin(), vecB.end(), std::back_inserter(vecA));
// merge
std::inplace_merge(vecA.begin(), vecA.begin()+mergesize, vecA.end());

您可以按如下方式组合加入+合并步骤

Vec vecC;
std::merge(vecA.begin(), vecA.end(),
            vecB.begin(), vecB.end(),
            std::back_insterter(vecC));

最后一步,删除重复项:

Vec::iterator pte = std::unique(vecC.begin(), vecC.end());
// dups now in [pte, vecC.end()), so optionally erase:
vecC.erase(pte, vecC.end());

两个向量中元素的顺序重要吗?如果没有,那么您可能应该改用集合。