如何解决在 C++ 中删除 Vector 中的元素及其重复项
我在 Internet 上搜索过并知道如何删除元素(使用 std::erase
)并找到元素的重复项然后将其删除(vec.erase(std::unique(vec.begin(),vec.end()),vec.end());
)。但所有方法都只删除一个元素或其重复项。
我想删除两个。
例如,使用这个向量:
std::vector<int> vec = {2,3,1,5,2,1};
我希望输出为:
{3}
我最初的想法是:
void removeDuplicatesandElement(std::vector<int> &vec)
{
std::sort(vec.begin(),vec.end());
int passednumber = 0; //To tell amount of number not deleted (since not duplicated)
for (int i = 0; i != vec.size(); i = passednumber) //This is not best practice,but I tried
{
if (vec[i] == vec[i+1])
{
int ctr = 1;
for(int j = i+1; j != vec.size(); j++)
{
if (vec[j] == vec[i]) ctr++;
else break;
}
vec.erase(vec.begin()+i,vec.begin()+i+ctr);
}
else passednumber++;
}
}
它奏效了。但是这段代码是多余的,运行时间为 O(n^2),所以我正在尝试寻找其他方法来解决问题(可能是我从未听说过的 STL 函数,或者只是改进代码)。>
解决方法
可能是这样的:
array
这在很大程度上依赖于 void removeDuplicatesandElement(std::vector<int> &vec) {
if (vec.size() <= 1) return;
std::sort(vec.begin(),vec.end());
int cur_val = vec.front() - 1;
auto pred = [&](const int& val) {
if (val == cur_val) return true;
cur_val = val;
// Look ahead to the next element to see if it's a duplicate.
return &val != &vec.back() && (&val)[1] == val;
};
vec.erase(std::remove_if(vec.begin(),vec.end(),pred),vec.end());
}
保证具有连续存储的事实。它不适用于任何其他容器。
您可以使用 STL 映射进行操作,如下所示:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
void retainUniqueElements(vector<int> &A){
unordered_map<int,int> Cnt;
for(auto element:A) Cnt[element]++;
A.clear(); //removes all the elements of A
for(auto i:Cnt){
if(i.second == 1){ // that if the element occurs once
A.push_back(i.first); //then add it in our vector
}
}
}
int main() {
vector<int> vec = {2,3,1,5,2,1};
retainUniqueElements(vec);
for(auto i:vec){
cout << i << " ";
}
cout << "\n";
return 0;
}
输出:
3
上述方法的时间复杂度: O(n)
上述方法的空间复杂度: O(n)
根据您搜索的内容,我们可以在向量中查找重复值,然后使用 Erase–remove idiom 清理向量。
#include <vector>
#include <algorithm>
#include <iostream>
void removeDuplicatesandElement(std::vector<int> &vec)
{
std::sort(vec.begin(),vec.end());
if (vec.size() < 2)
return;
for (int i = 0; i < vec.size() - 1;)
{
// This is for the case we emptied our vector
if (vec.size() < 2)
return;
// This heavily relies on the fact that this vector is sorted
if (vec[i] == vec[i + 1])
vec.erase(std::remove(vec.begin(),(int)vec[i]),vec.end());
else
i += 1;
}
// Since all duplicates are removed,the remaining elements in the vector are unique,thus the size of the vector
// But we are not returning anything or any reference,so I'm just gonna leave this here
// return vec.size()
}
int main()
{
std::vector<int> vec = {2,1};
removeDuplicatesandElement(vec);
for (auto i : vec)
{
std::cout << i << " ";
}
std::cout << "\n";
return 0;
}
输出:3
时间复杂度:O(n)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。