C++ - 将一个Vector附加到另一个,删除重复项?

Tri*_*tan 3 c++ vector

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

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

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

vectorAlpha:

First line of alpha
An alpha line
An alpha line
Some line
Alpha fifth line
Run Code Online (Sandbox Code Playgroud)

vectorBeta:

Beta first line
A beta line
A beta line
Some line
Beta fifth line
Run Code Online (Sandbox Code Playgroud)

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

First line of alpha
An alpha line
Some line
Alpha fifth line
Beta first line
A beta line
Beta fifth line
Run Code Online (Sandbox Code Playgroud)

虽然第二种方法只是两个数组合并,但第二个向量中的'Some 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
Run Code Online (Sandbox Code Playgroud)

用于这两个appraoches的C++代码是什么?

seh*_*ehe 5

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

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());
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式组合联接+合并步骤

Vec vecC;
std::merge(vecA.begin(), vecA.end(),
            vecB.begin(), vecB.end(),
            std::back_insterter(vecC));
Run Code Online (Sandbox Code Playgroud)

最后一步,删除重复项:

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


seh*_*ehe 5

因为很明显

  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));
}
Run Code Online (Sandbox Code Playgroud)

您可能希望根据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);
    }
};
Run Code Online (Sandbox Code Playgroud)

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

干杯