C ++相当于Java ArrayList方法removeAll

时间:2015-03-11 02:55:23

标签: java c++ vector arraylist

Java ArrayList removeAll()方法将集合作为参数,并从调用该方法的ArrayList中删除此集合。如何在c ++中的vector上完成等效操作?

4 个答案:

答案 0 :(得分:0)

std::vector中没有这样的方法。

标准库的设计理念是我们不会在类中实现所有内容。相反,有许多算法可以在容器上运行。

http://en.cppreference.com/w/cpp/algorithm

不幸的是,标准算法之间也没有等价物。但是你可以写一个基于它们的算法。

#include <algorithm>

template <class Container, class RemoveTargetContainer>
typename Container::iterator remove_for(Container& container, const RemoveTargetContainer& targets)
{
    auto container_first = std::begin(container);
    auto container_last = std::end(container);

    std::for_each(std::begin(targets), std::end(targets),
        [&](typename RemoveTargetContainer::const_reference target)
        {
            container_last = std::remove(container_first, container_last, target);
        }
    );

    return container_last;
}

这是用法:

#include <iostream>
#include <vector>
#include <deque>

int main()
{
    std::vector<int> myContainer { 1,2,3,4,5,6,7,8 };
    std::deque<int> removalTargets { 1,3,5,7 };

    myContainer.erase(remove_for(myContainer, removalTargets), std::end(myContainer));

    for (const auto& x : myContainer)
        std::cout << x << " ";
    std::cout << std::endl;
}

PS:我不喜欢名字removeAll。这是误导。

答案 1 :(得分:0)

这是一个通用的解决方案:

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

// Remove all in c2 from c1
template<typename Collection1, typename Collection2>
void removeAll(Collection1& c1, const Collection2& c2)
{
    for(auto&& i: c2)
        c1.erase(std::remove_if(c1.begin(), c1.end(), [i](decltype(i) i1){return i == i1;}), c1.end());
}

int main()
{
    std::vector<int> v1 {1, 5, 3, 6, 4, 6, 2, 6, 7};
    std::set<int> v2 {5, 6, 2};

    removeAll(v1, v2);

    // display results
    for(auto&& i: v1)
        std::cout << i << '\n';
}

<强>输出:

1
3
4
7

答案 2 :(得分:0)

我毫不怀疑上面的答案是有效的解决方案,我只是不能让它们编译。我是一名C ++初学者,尚未研究过通用用法,但编译器抱怨每个解决方案中的方括号([])。我最终编写了自己的解决方案。我确信它会让c ++兽医畏缩,但它似乎有效。在这里。

#include <vector>

void removeAll(std::vector<int>& original, const std::vector<int>& partition1){ 
for (int i=0; i<original.size();i++) {
    for (int x: partition1) {
        if (x == original[i]){
           original.erase(original.begin() + i);
           --i;
           break;
        }
     }
  }
}

答案 3 :(得分:-1)

在{+ 1}}的C ++中没有这样的方法。一种方法是,与其他建议的实现不同,它具有非常好的运行时,是将第二个集合转换为std::vectorstd::set,并迭代第一个向量,仅保留执行的元素不属于集合,类似于:

std::unordered_set

但这只适用于template <class T> void removeAll(std::vector<T>& in, const std::vector<T>& removeWhat) { std::set<T> st(removeWhat.begin(), removeWhat.end()); size_t newSize = 0; for (size_t i = 0; i < in.size(); ++ i) { if (0 == st.count(in[i])) { in[newSize ++] = in[i]; } } in.resize(newSize); } 操作符T超载的情况(<的要求)。它适用于整数,因此它适用于您的特定情况。