[英]C++ equivalent to Java ArrayList method removeAll
Java ArrayList
removeAll()
方法將一個集合作為參數,並從調用該方法的ArrayList
中刪除此集合。 如何在c ++中的vector
上完成等效動作?
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
。 這是誤導。
這是一個通用的解決方案:
#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
毫無疑問,以上答案是有效的解決方案,但我無法讓它們進行編譯。 我是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;
}
}
}
}
C ++中沒有針對std::vector
。 與其他建議的實現方式不同,一種具有良好運行時的方法是將第二個集合轉換為std::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
運算符<
重載(對std::set
要求)時有效。 它用於整數,因此將在您的特定情況下工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.