1、先看c++如何去掉vector中的基本数据类型的重复元素
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
/**
* vector去除重复元素
* @tparam T
* @param result
* @return
*/
template<typename T>
vector<T> vector_distinct(vector<T> result) {
sort(result.begin(), result.end());
auto ite = unique(result.begin(), result.end());
//删除重复的元素
result.erase(ite, result.end());
return result;
}
/**
* 利用set为vector数组去重
* @tparam T
* @param vec
* @return
*/
template<typename T>
vector<T> vectorToset_distinct(vector<T> vec) {
set<T> st(vec.begin(), vec.end());
vec.assign(st.begin(), st.end());
return vec;
}
int main() {
vector<string> v_str1 = {"a", "b", "c", "d", "e", "b"};
vector<string> v_res = vector_distinct(v_str1);
vector<string> vs_res = vectorToset_distinct(v_str1);
cout << "v_str1=";
for (auto v:v_str1) {
cout << v << ",";
}
cout << endl;
cout << "v_res=";
for (auto v:v_res) {
cout << v << ",";
}
cout << endl;
cout << "vs_res=";
for (auto v:vs_res) {
cout << v << ",";
}
cout << endl;
}
2、再看c++如何去掉vector中的结构体类型的重复元素
#include <vector>
#include <string>
#include <algorithm>
#include <stdio.h>
class foobar
{
public:
std::string token;
std::string item;
int number;
// 重载操作符
bool operator<(const foobar& rhs) { return (*this).token < rhs.token;};
bool operator>(const foobar& rhs) { return (*this).token > rhs.token;};
bool operator==(const foobar& rhs) { return (*this).token == rhs.token;}
};
bool sort_token(const foobar& s1, const foobar& s2)
{
return s1.token.compare(s2.token) < 0;
}
int main(int argc, char* argv[])
{
std::vector<foobar> vFoo;
foobar tmp;
tmp.token = "osd_1";
tmp.item = "OSD11111";
tmp.number = 1;
vFoo.push_back(tmp);
tmp.token = "osd_0";
tmp.item = "OSD111111";
tmp.number = 0;
vFoo.push_back(tmp);
tmp.token = "osd_2";
tmp.item = "OSD22222";
tmp.number = 2;
vFoo.push_back(tmp);
tmp.token = "osd_3";
tmp.item = "OS3330";
tmp.number = 3;
vFoo.push_back(tmp);
tmp.token = "osd_4";
tmp.item = "OS444444444444444";
tmp.number = 4;
vFoo.push_back(tmp);
tmp.token = "osd_1";
tmp.item = "OS5555555554444";
tmp.number = 5;
vFoo.push_back(tmp);
printf("before sort: \n");
for (unsigned int i = 0; i < vFoo.size(); i++)
{
printf("token: %s font: %d item: %s\n", vFoo[i].token.c_str(), vFoo[i].number, vFoo[i].item.c_str());
}
std::sort(vFoo.begin(),vFoo.end(),sort_token); // 先排序
// 去除重复项
std::vector<foobar>::iterator unque_it = std::unique(vFoo.begin(), vFoo.end());
vFoo.erase(unque_it, vFoo.end());
printf("after unque: \n");
for (unsigned int i = 0; i < vFoo.size(); i++)
{
printf("token: %s font: %d item: %s\n", vFoo[i].token.c_str(), vFoo[i].number, vFoo[i].item.c_str());
}
return 0;
}
3、聚类分析的方法,把cad图元,例如点,圆等,重复的(x,y)点坐标去掉。
void clusterAnalyze(const std::vector<cv::Point2f> &vtCenter1, const std::vector<float> &vtRadius1,
std::vector<cv::Point2f> &vtCenter2, std::vector<float> &vtRadius2, double disThreshold)
{
if (vtCenter1.size() <= 1)
{
vtCenter2 = vtCenter1;
vtRadius2 = vtRadius1;
return;
}
//聚类分析,把点与点距离相近的,归为同一类
std::vector<int> vtLabels; //标志,0,1,2,3...,同一类就用相同的数字标记
int dis = disThreshold * disThreshold; //点与点距离的平方值
int num_labels = cv::partition(vtCenter1, vtLabels, [dis](const cv::Point2f &p1, const cv::Point2f &p2) {
return ((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)) < dis;
});
vtCenter2.resize(num_labels);
vtRadius2.resize(num_labels);
for (size_t i = 0; i < vtCenter1.size(); i++)
{
vtCenter2[vtLabels[i]] = vtCenter1[i];
vtRadius2[vtLabels[i]] = vtRadius1[i];
}
}
x、参考文献
[C++]vector去除重复元素 - Xu_Lin - 博客园
使用STL去除std::vector自定义结构体重复项_李迟的专栏-CSDN博客