从数组中删除唯一元素的最有效方法 在C++中,从数组中剔除元素的有效方法是什么?
给定的数组:从数组中删除唯一元素的最有效方法 在C++中,从数组中剔除元素的有效方法是什么?,c++,arrays,algorithm,c++11,duplicates,C++,Arrays,Algorithm,C++11,Duplicates,给定的数组: 9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3 // keep duplicates, delete uniques 输出: 9, 4, 9, 3, 1, 4, 6, 6, 3, 6, 9, 1, 3 // all duplicates void rmdup(int*数组,int长度) { int*当前,*结束=数组+长度-1; 用于(当前=阵列+1;阵列我将使用C++集,因为它们的对数复杂性(编辑
9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3 // keep duplicates, delete uniques
输出:
9, 4, 9, 3, 1, 4, 6, 6, 3, 6, 9, 1, 3 // all duplicates
void rmdup(int*数组,int长度)
{
int*当前,*结束=数组+长度-1;
用于(当前=阵列+1;阵列 (当前< P>我将使用C++集,因为它们的对数复杂性(编辑:如所说)。< /P>
此解决方案的算法复杂度为O(n logn):
#include <set>
#include <iostream>
int main(int argc, char** argv) {
int nums[] = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3};
std::set<int> s;
std::set<int> dups;
for (int i = 0; i < 19; ++i)
if (!s.insert(nums[i]).second)
dups.insert(nums[i]);
for (int i = 0; i < 19; ++i)
if (dups.find(nums[i]) != dups.end())
std::cout << " " << nums[i];
std::cout << std::endl;
return 0;
}
#包括
#包括
int main(int argc,字符**argv){
int nums[]={9,8,4,9,21,3,1,4,6,2,5,6,7,12,3,6,9,1,3};
std::集s;
std::设置DUP;
对于(int i=0;i<19;++i)
如果(!s.insert(nums[i])秒)
重复插入(nums[i]);
对于(int i=0;i<19;++i)
if(dups.find(nums[i])!=dups.end()
我可能会这样做:
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
int main(int argc, char* argv[]) {
std::vector<int> nums = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2,
5, 6, 7, 12, 3, 6, 9, 1, 3};
// build histogram
std::map<int, int> counts;
for (int i : nums) ++counts[i];
// copy elements that appear more than once
std::vector<int> result;
std::copy_if(nums.begin(), nums.end(),
std::back_inserter(result),
[&](int x){ return counts[x] > 1; });
// print result
for (int i : result) {
std::cout << i << " ";
}
std::cout << "\n";
}
这是两个过程,您需要构建一个BST。如果您觉得这太慢,您可以尝试使用std::unordered_map
构建直方图,它在插入和查找方面具有更好的复杂性特征
如果希望从原始向量中删除重复项,而不是构建另一个向量,则可以使用。(这是留给读者的练习。)这是怎么回事
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main(int argc, char** argv) {
vector<int> nums = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3};
std::set<int> s;
vector<int> dups;
for(auto i:nums)
if (!s.insert(i).second)
dups.push_back(i);
for_each(dups.begin(),dups.end(),[](int a){cout<<a<<" ";});
cout << endl;
return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,字符**argv){
向量nums={9,8,4,9,21,3,1,4,6,2,5,6,7,12,3,6,9,1,3};
std::集s;
矢量DUP;
用于(自动i:nums)
如果(!s.插入(i).秒)
重复。推回(i);
对于每个(dups.begin(),dups.end(),[](int a){couta loop with book keeping in astd::set
或std::unordered_set
@Jenin是否允许对原始数组进行排序?loop,将元素添加到std::set
,如果尝试时元素已在集合中,则将其添加到重复项列表中。这是昨天才提出的问题……你至少应该尝试解决这个问题你的电脑有问题吗own@VladfromMoscow,不,不允许原始的与赋值相关的排序函数没有意义。一次通过,但输出与需要的不同使用无序映射
而不是映射
可以使它快一点“我认为你不会得到明显快一点的结果。”实际上,它可以用无序映射来完成。它不是O(n logn),而是O(n)。我认为这算是“明显更快”。@JimMischel虽然O(n)在理论上比O(n logn)快,但在实践中不一定明显快。(FWIW我删除了该部分,赞成在std::unordered_映射上添加注释
)而unordered_-map
的操作复杂度平均为O(n)
而不是最坏的情况。@DAle:是的,unordered_-map
的平均情况复杂度为O(n),最坏情况复杂度为O(n log n)。最糟糕的情况是,如果插入的项目都落在非常少的存储桶中。也就是说,大量的哈希冲突。如果没有特意生成的病理数据,我在实践中从未见过这种情况发生。
$ g++ test.cc -std=c++11 && ./a.out
9 4 9 3 1 4 6 6 3 6 9 1 3
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main(int argc, char** argv) {
vector<int> nums = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3};
std::set<int> s;
vector<int> dups;
for(auto i:nums)
if (!s.insert(i).second)
dups.push_back(i);
for_each(dups.begin(),dups.end(),[](int a){cout<<a<<" ";});
cout << endl;
return 0;
}