c++内置工具备忘录

文章介绍了C++中如何对自定义数据类型进行排序,包括单一属性和多个属性的排序,并展示了使用std::unique去除容器内重复元素的方法。同时,文章讨论了break和continue在循环控制中的区别,并给出了实际案例。此外,还提及了反三角函数acos在解算角度时的应用和理解要点。
摘要由CSDN通过智能技术生成

 一、关于排序

①对单个属性值进行排序,比如xyz或者intensity之类的;

②对多个属性进行排序,比如先按x排序,当x相同时再按y排序;(其他类似排序需求,以此类推)

#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include<vector>
#include<algorithm>
 
using namespace std;
using namespace pcl;

//因为需要比较的数据不是c++内置的可以直接用于比较的数据类型,所以要自己定义排序规则函数
bool comparefunc(pcl::PointXYZI &p1, pcl::PointXYZI &p2)
{
	if (p1.x == p2.x)
	{
		return p1.y < p2.y;//当x相同,按y升排序
	}
	else
	{
		return p1.x < p2.x;//x不同,按x升排序
	}
}

void testcompare()
{
	pcl::PointCloud<pcl::PointXYZI>::Ptr seedpoint(new pcl::PointCloud<pcl::PointXYZI>);
	pcl::PointXYZI temp,temp1,temp2, temp3, temp4, temp5, temp6;
	temp.x = 91; temp.y = 88; temp.z = 2; temp.intensity = 15000;
	temp1.x = 91; temp1.y = 288; temp1.z = 1; temp1.intensity = 10000;
	temp2.x = 79; temp2.y = 78; temp2.z = 5; temp2.intensity = 15005;
	temp3.x = 79; temp3.y = 78; temp3.z = 4; temp3.intensity = 15005;
	temp4.x = 41; temp4.y = 58; temp4.z = 1; temp4.intensity = 10800;
	temp5.x = 779; temp5.y = 718; temp5.z = 6; temp5.intensity = 15005;
	temp6.x = 91; temp6.y = 78; temp6.z = 8; temp6.intensity = 15905;
	seedpoint->points.push_back(temp);
	seedpoint->points.push_back(temp1);
	seedpoint->points.push_back(temp2);
	seedpoint->points.push_back(temp3);
	seedpoint->points.push_back(temp4);
	seedpoint->points.push_back(temp5);
	seedpoint->points.push_back(temp6);

	cout << "排序前————————————————" << endl;
	for (int i = 0; i < seedpoint->points.size(); i++)
	{
		cout << seedpoint->points[i].x << " ," << seedpoint->points[i].y << " ," << seedpoint->points[i].z << " ," << seedpoint->points[i].intensity << endl;
	}

    cout << "仅按x降排序————————————————" << endl;
    //单一属性排序,x可以改成任何其他属性值是数字或系统可以直接比较的字段
    std::sort(seedpoint->points.begin(), seedpoint->points.end(),//按x降排序
		[](pcl::PointXYZI & p1, pcl::PointXYZI & p2) {return p1.x > p2.x; });
   for (int i = 0; i < seedpoint->points.size(); i++)
	{
		cout << seedpoint->points[i].x << " ," << seedpoint->points[i].y << " ," << seedpoint->points[i].z << " ," << seedpoint->points[i].intensity << endl;
	}

	cout << "先按x升排序,x相同则按y升排序————————————————" << endl;
	sort(seedpoint->points.begin(), seedpoint->points.end(),comparefunc);//调用自定义的排序函数,按照制定规则排序
	for (int i = 0; i < seedpoint->points.size(); i++)
	{
		cout << seedpoint->points[i].x << " ," << seedpoint->points[i].y << " ," << seedpoint->points[i].z << " ," << seedpoint->points[i].intensity << endl;
	}
}

int main()
{		
	testcompare();
	system("pause");
	return 0;
}

二、unique,去除容器内重复元素

经常使用vector容器,容器本身没有自带的去除重复元素的方法,但是偶尔又有需求。

set容器是不允许插入相同元素的,但元素需要是c++预置的数据类型,如果是存储自定义数据类型是无法直接比较的。

这里可以利用unique函数,剔除重复元素,只保留一个。使用unique方法前,需要对初始数据进行排序。

参考:C++ std::unique用法及代码示例 - 纯净天空 (vimsky.com)

“std::unique用于删除在range [first,last)中连续存在的任何元素的重复项。它对连续存在相同元素的范围内存在的所有sub-groups执行此任务。

  • 它不会删除所有重复的元素,而是通过将序列中存在的下一个元素替换为与当前要替换的当前元素不重复的下一个元素来消除重复性。所有被替换的元素都处于未指定状态。
  • 此函数的另一个有趣的函数是,它在删除元素后不会更改容器的大小,它仅返回一个指向容器新端的指针,并根据此指针来调整容器的大小或删除容器的大小。垃圾元素。”
#include<iostream>
#include<string>
#include<vector>
#include<math.h>
#include<cmath>
#include<algorithm> 

using namespace std;

class my_point    //自定义数据类型
{
public:
	double m_x;
	double m_y;
	double m_z;
	double m_intensity;

	my_point(double x,double y,double z,double intensity)
	{
		this->m_x = x;
		this->m_y = y;
		this->m_z = z;
		this->m_intensity = intensity;
	}
};
bool ISsame(my_point p1, my_point p2)  //自定义比较函数
{
	if (p1.m_x == p2.m_x&&p1.m_y == p2.m_y&&p1.m_z == p2.m_z&&p1.m_intensity == p2.m_intensity)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
void delesame()
{
	vector<my_point> temp;
	my_point mp1(2, 5, 8, 5.3);
	my_point mp2(2, 5, 8, 5.3);
	my_point mp3(1, 5, 8, 5.2);
	my_point mp4(2, 5, 8, 4.9);
	temp.push_back(mp1);
	temp.push_back(mp2);
	temp.push_back(mp3);
	temp.push_back(mp4);
	cout << "没删除重复元素前:" << endl;
	for (int i = 0; i < temp.size(); i++)
	{
		cout << temp[i].m_x << " ," << temp[i].m_y << " ," << temp[i].m_z << " ," << temp[i].m_intensity << endl;
	}
	cout << "删除重复元素后:" << endl;
	std::sort(temp.begin(), temp.end(),//按x升排序
		[](my_point & p1, my_point & p2) {return p1.m_x < p2.m_x; });
	std::vector<my_point>::iterator unque_it = std::unique(temp.begin(), temp.end(), ISsame);//
	temp.erase(unque_it, temp.end());//去除重复项
	for (int i = 0; i < temp.size(); i++)
	{
		cout << temp[i].m_x << " ," << temp[i].m_y << " ," << temp[i].m_z << " ," << temp[i].m_intensity << endl;
	}
}

int main()
{
    delesame();
}

三、关于 break和continue用法

 这篇解释的很详细C++ break和continue用法详解 (biancheng.net)

这两个平时用的少,但是真要用的时候确实是有点分不太清。

下面是我自己使用的一个案例:

vector<pcl::PointCloud<pcl::PointXYZI>::Ptr> slices;
	double Xmax = groundpoint->points.front().x;
    double Xmin = groundpoint->points.back().x;
	int n =abs( ceil(Xmax-Xmin)/0.5);//结果向上取整,得到切片总数,切片宽度0.5
	
	for (int i = 1; i < n; i++)
	{
		pcl::PointCloud<pcl::PointXYZI>::Ptr tempcloud(new pcl::PointCloud<pcl::PointXYZI>);//切块i			
		while (groundpoint->points.size()>0)
		{
			if (groundpoint->points.back().x < (Xmin + 0.5*i))
			{
				tempcloud->points.push_back(groundpoint->points.back());
				groundpoint->points.pop_back();

			}
			else
			{
				break;//这里如果用continue的话,就还会在while的循环里面;(那我就只能得到第一段切片了,其他不属于第一段切片的点都会被弹出)
                     //用break,就跳出wihle这层,让for循环执行完一遍,使得i+1了;
			}
		}	
		slices.push_back(tempcloud);
    }

四、关于反三角函数acos

一般在解算角度的时候会需要用到反三角函数,但好像一直对它的函数返回值有误解。

这篇文章解释的很清楚c++ acos函数_acos()函数以及C ++中的示例_cumubi7453的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值