容器Vector判断是否有重复元素
- STL中的容器有:顺序容器(list,queue,vector )和关联容器(map,set、multimap、multiset)
- vector 的存储结构是数组,其它是链表;
- vector和set都实现了对一类对象的存储,都可以查找、添加、删除、修改等;
- vector支持随机访问,而set不支持(下标访问)。
- vector可以存储重复值,其元素与存储位置与操作有关;
- set 其元素相当于键值,不可以存储重复值(multiset除外),有默认顺序: 从小到大;
使用Set容器判断内置类型
判断vector中是否有相同元素,可利用set中没有重复元素的特性:
把vector中的元素塞到set中,看两个容器中的元素个数是否相同
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
int main()
{
std::vector<int> vecInt{ 1,2,3,1,1 }; //vecInt: 1 2 3 1 1
// std::for_each(vecInt.begin(), vecInt.end(),[](int iT) {std::cout << iT << " "; });
//
std::set<int>setInt (vecInt.begin(), vecInt.end()); //setInt: 1 2 3
//std::for_each(setInt.begin(), setInt.end(),[](int iT) {std::cout << iT << " "; });
std::cout << "IsHaveSameElement: " << (vecInt.size() != setInt.size())<< std::endl; //IsHaveSameElement: 1
return 0;
}
使用Set容器判断自定义类型
set中存放元素有默认顺序: 从小到大
自定义结构体时需要重载比较运算符
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
struct ROI
{
int iId = 0;
std::string szName = "";
int operator<(const ROI& obj) const
{
return iId < obj.iId; //指定按照iId从小到大排序
}
};
int main()
{
std::vector<ROI> vecInt{ {0,"a"},{1,"b"},{0,"c"} }; //{0,a} {1,b} {0,c}
//std::for_each(vecInt.begin(), vecInt.end(), [](ROI obj) {std::cout << "{" << obj.iId << "," << obj.szName << "}" << " "; });
std::set<ROI>setInt (vecInt.begin(), vecInt.end()); //{0,a} {1,b}
//std::for_each(setInt.begin(), setInt.end(), [](ROI obj) {std::cout << "{" << obj.iId << "," << obj.szName << "}" << " "; });
std::cout << "IsHaveSameElement: " << (vecInt.size() != setInt.size())<< std::endl; //IsHaveSameElement: 1
return 0;
}
可以看出完全按照iId的大小来排序的,且忽略了szName,只要iId相同就认为此对象相同
若想多个元素都相同时才认为此对象相同呢,可以模拟set容器
使用sort和unique函数判断vector中自定义类型
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
struct ROI
{
int iId = 0;
std::string szName = "";
bool operator == (const ROI& obj) const
{
return iId == obj.iId && szName == obj.szName;
}
int operator<(const ROI& obj) const
{
return iId < obj.iId;
}
};
void PrintLog(std::vector<ROI> vec)
{
std::for_each(vec.begin(), vec.end(),
[](ROI obj) {std::cout << "{" << obj.iId << "," << obj.szName << "}" << " "; });
std::cout << "" << std::endl;
}
int main()
{
std::vector<ROI> vecInt{ {0,"a"},{1,"b"},{0,"c"},{1,"b"} };
PrintLog(vecInt); //{0,a} {1,b} {0,c}{1,b}
std::vector<ROI> vecInt1 = vecInt;
std::sort(vecInt1.begin(), vecInt1.end()); //排序
PrintLog(vecInt1); //{0,a} {0,c} {1,b} {1,b}
auto iter = std::unique(vecInt1.begin(), vecInt1.end());
vecInt1.erase(iter, vecInt1.end());
PrintLog(vecInt1); //{0,a} {0,c} {1,b}
std::cout << "IsHaveSameElement: " << (vecInt.size() != vecInt1.size())<< std::endl; //IsHaveSameElement: 1
return 0;
}
若容器中的元素已经经过排序,可以使用 std::unique与erase联合使用,移除容器范围内的连续重复元素。