C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型
用自己定义的数据结构作为rtree的key。
// rTree的key
struct OverlapKey
{using BDPoint = boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian>; //双精度的点using MyRTree = boost::geometry::index::rtree<OverlapKey, boost::geometry::index::linear<16> >;BDPoint GetKey() { return key; }std::wstring id;//keyBDPoint key;std::list<DgnHistory::FarElementID> mCurveLst;// std::greater<double>>, std::less<int>> mData;/*--------------------------------------------------------------------------------------**//*** 将对方向相同的曲线(一般情况下是直线)进行分类, * Created by Simon.Zou on 9/2021+---------------+---------------+---------------+---------------+---------------+-----------*///std::set<DataPtr, Data::DataSort> mData; void AddData(DgnHistory::FarElementID data){mCurveLst.push_back(data);}OverlapKey(){boost::uuids::uuid a_uuid = boost::uuids::random_generator()(); // 这里是两个() ,因为这里是调用的 () 的运算符重载id = boost::uuids::to_wstring(a_uuid);key.set<0>(0);key.set<1>(0);key.set<2>(0);//ICurvePrimitivePtr = NULL;}OverlapKey(const OverlapKey& r){*this = r;}OverlapKey(OverlapKey&& r){this->id = r.id;this->key = r.key;mCurveLst = r.mCurveLst;r.id = L"";r.key.set<0>(0);r.key.set<1>(0);r.key.set<2>(0);r.mCurveLst.clear();}OverlapKey& operator=(const OverlapKey& r){this->id = r.id;this->key = r.key;mCurveLst = r.mCurveLst;//this->ICurvePrimitivePtr = r.ICurvePrimitivePtr;return *this;}OverlapKey& operator=(OverlapKey&& r){this->id = r.id;this->key = r.key;mCurveLst = r.mCurveLst;//this->ICurvePrimitivePtr = r.ICurvePrimitivePtr;r.id = L"";r.key.set<0>(0);r.key.set<1>(0);r.key.set<2>(0);r.mCurveLst.clear();return *this;}//rTree.remove(...)函数会用到bool operator == (const OverlapKey& o) const{bool b1 = fabs(key.get<0>() - o.key.get<0>()) < 0.001;bool b2 = fabs(key.get<1>() - o.key.get<1>()) < 0.001;bool b3 = fabs(key.get<2>() - o.key.get<2>()) < 0.001;if (b1 && b2 && b3)return true;_SaveLog_Info_return_false("return false")}
};/*--------------------------------------------------------------------------------------**//**
* 为了能把自己的数据结构OverlapKey用到boost的rtree里,创建此特化
* Created by Simon.Zou on 9/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
template <>
struct boost::geometry::index::indexable<OverlapKey>
{typedef OverlapKey::BDPoint result_type; //这个不能缺少const OverlapKey::BDPoint& operator()(const OverlapKey& c) const{return c.key;}
};
/*--------------------------------------------------------------------------------------+
| HchxAlgorithm.cpp
|
+--------------------------------------------------------------------------------------*/
#include "HchxUnitTestPch.h"#include "gtest\gtest.h"using namespace std;
using namespace boost;USING_NAMESPACE_BENTLEY_ECOBJECT;#include <cmath>
#include <vector>
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/assign/std/vector.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/io/dsv/write.hpp>
#include <boost/foreach.hpp>bool boost_test1()
{namespace bg = boost::geometry;namespace bgi = boost::geometry::index;typedef bg::model::point<double, 2, bg::cs::cartesian> DPoint;typedef bg::model::box<DPoint> DBox;typedef bg::model::polygon<DPoint, false, false> DPolygon; // ccw, open polygontypedef std::pair<DBox, unsigned> DValue;std::vector<DPolygon> polygons;//构建多边形for (unsigned i = 0; i < 10; ++i){//创建多边形DPolygon p;for (float a = 0; a < 6.28316f; a += 1.04720f){float x = i + int(10 * ::cos(a))*0.1f;float y = i + int(10 * ::sin(a))*0.1f;p.outer().push_back(DPoint(x, y));}//插入polygons.push_back(p);}//打印多边形值std::cout << "generated polygons:" << std::endl;BOOST_FOREACH(DPolygon const& p, polygons)std::cout << bg::wkt<DPolygon>(p) << std::endl;//创建R树bgi::rtree< DValue, bgi::rstar<16, 4> > rtree; //最大最小//计算多边形包围矩形并插入R树for (unsigned i = 0; i < polygons.size(); ++i){//计算多边形包围矩形DBox b = bg::return_envelope<DBox>(polygons[i]);//插入R树rtree.insert(std::make_pair(b, i));}//按矩形范围查找DBox query_box(DPoint(0, 0), DPoint(5, 5));std::vector<DValue> result_s;rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));//5个最近点std::vector<DValue> result_n;rtree.query(bgi::nearest(DPoint(0, 0), 5), std::back_inserter(result_n));// note: in Boost.Geometry the WKT representation of a box is polygon// note: the values store the bounding boxes of polygons// the polygons aren't used for querying but are printed// display resultsstd::cout << "spatial query box:" << std::endl;std::cout << bg::wkt<DBox>(query_box) << std::endl;std::cout << "spatial query result:" << std::endl;BOOST_FOREACH(DValue const& v, result_s)std::cout << bg::wkt<DPolygon>(polygons[v.second]) << std::endl;std::cout << "knn query point:" << std::endl;std::cout << bg::wkt<DPoint>(DPoint(0, 0)) << std::endl;std::cout << "knn query result:" << std::endl;BOOST_FOREACH(DValue const& v, result_n)std::cout << bg::wkt<DPolygon>(polygons[v.second]) << std::endl;return true;
}void boost_test2()
{namespace bg = boost::geometry;namespace bgi = boost::geometry::index;typedef bg::model::d2::point_xy<double, boost::geometry::cs::cartesian> DPoint; //双精度的点typedef bg::model::polygon<DPoint, false, false> DPolygon; // ccw, open polygontypedef bg::model::box<DPoint> DBox; //矩形typedef std::pair<DBox, unsigned> Value;//创建R树 linear quadratic rstar三种算法bgi::rtree<Value, bgi::quadratic<16>> rtree;//采用quadratic algorithm,节点中元素个数最多16个//bgi::rtree<Value, bgi::rstar<32>> rtree;//采用quadratic algorithm,节点中元素个数最多16个//bgi::rtree<Value, bgi::linear<32>> rtree;//采用quadratic algorithm,节点中元素个数最多16个//bgi::rtree<std::pair<DBox, std::string>, bgi::rstar<16> > rtree;//填充元素
// for (unsigned i = 0; i < 10; ++i)
// {
// DBox b(DPoint(i + 0.0f, i + 0.0f), DPoint(i + 0.5f, i + 0.5f));
// rtree.insert(std::make_pair(b, i));//r树插入外包围矩形 i为索引
// }DBox b1(DPoint(0.0f, 0.0f), DPoint(1.0f, 1.0f));rtree.insert(std::make_pair(b1, 0));//r树插入外包围矩形 i为索引DBox b2(DPoint(-1.0f, -1.0f), DPoint(0.0f, 0.0f));rtree.insert(std::make_pair(b2, 1));//r树插入外包围矩形 i为索引DBox b3(DPoint(0.0f, 0.0f), DPoint(1.5f, 1.5f));rtree.insert(std::make_pair(b3, 2));//r树插入外包围矩形 i为索引//查询与矩形相交的矩形索引DBox query_box(DPoint(-0.1f, -0.1f), DPoint(1.2f, 1.2f));std::vector<Value> result_s;//https://www.boost.org/doc/libs/1_54_0/libs/geometry/doc/html/geometry/spatial_indexes/queries.html//查出与query_box相交的所有box。可以overlaps,也可以是包含关系。//rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));//被query_box完全覆盖的所有box//rtree.query(bgi::covered_by(query_box), std::back_inserter(result_s));//查出所有包含query_box的box。注意是“包含”。如果仅仅是相交,是不会放到结果集中的。rtree.query(bgi::covers(query_box), std::back_inserter(result_s)); //查出与query_box不相交的集合。这些集合和query_box没有任何重叠。//rtree.query(bgi::disjoint(query_box), std::back_inserter(result_s));//查出与query_box相交的集合。与intersects不同的是:如果query_box在box内部,那么这个box不会被记录到结果集。//rtree.query(bgi::overlaps(query_box), std::back_inserter(result_s));//查到被query_box完全包含的box。不包含那种相交的//rtree.query(bgi::within(query_box), std::back_inserter(result_s));//rtree.bgi::query(bgi::intersects(box), std::back_inserter(result));/*--------------------------------------------------------------------------------------**//*** 支持ring和polygon Commented by Simon.Zou on 5/2021+---------------+---------------+---------------+---------------+---------------+-----------*///查找5个离点最近的索引std::vector<Value> result_n;rtree.query(bgi::nearest(DPoint(0, 0), 5), std::back_inserter(result_n));//显示值std::cout << "spatial query box:" << std::endl;std::cout << bg::wkt<DBox>(query_box) << std::endl;std::cout << "spatial query result:" << std::endl;//BOOST_FOREACH(Value const& v, result_s)// std::cout << bg::wkt<DBox>(v.first) << " - " << v.second << std::endl;std::cout << "knn query point:" << std::endl;std::cout << bg::wkt<DPoint>(DPoint(0, 0)) << std::endl;std::cout << "knn query result:" << std::endl;//BOOST_FOREACH(Value const& v, result_n)// std::cout << bg::wkt<DBox>(v.first) << " - " << v.second << std::endl;
}void boost_test3()
{using namespace boost::assign;typedef boost::geometry::model::d2::point_xy<double> point_xy;// Create points to represent a 5x5 closed polygon.std::vector<point_xy> points;points +=point_xy(0, 0),point_xy(0, 5),point_xy(5, 5),point_xy(5, 0),point_xy(0, 0);// Create a polygon object and assign the points to it.boost::geometry::model::polygon<point_xy> polygon;boost::geometry::assign_points(polygon, points);std::cout << "Polygon " << boost::geometry::dsv(polygon) <<" has an area of " << boost::geometry::area(polygon) << std::endl;
}/*--------------------------------------------------------------------------------------**//**
* 用polygon来查询 Commented by Simon.Zou on 5/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
void boost_test4()
{namespace bg = boost::geometry;namespace bgi = boost::geometry::index;typedef bg::model::d2::point_xy<double, boost::geometry::cs::cartesian> DPoint; //双精度的点typedef bg::model::polygon<DPoint, false, false> DPolygon; // ccw, open polygontypedef bg::model::box<DPoint> DBox; //矩形typedef std::pair<DBox, unsigned> Value;//创建R树 linear quadratic rstar三种算法bgi::rtree<Value, bgi::quadratic<16>> rtree;//采用quadratic algorithm,节点中元素个数最多16个//bgi::rtree<Value, bgi::rstar<32>> rtree;//采用quadratic algorithm,节点中元素个数最多16个//bgi::rtree<Value, bgi::linear<32>> rtree;//采用quadratic algorithm,节点中元素个数最多16个//bgi::rtree<Value, bgi::rstar<16>> rtree;//采用quadratic algorithm,节点中元素个数最多16个//bgi::rtree<std::pair<DBox, std::string>, bgi::rstar<16> > rtree;//填充元素
// for (unsigned i = 0; i < 10; ++i)
// {
// DBox b(DPoint(i + 0.0f, i + 0.0f), DPoint(i + 0.5f, i + 0.5f));
// rtree.insert(std::make_pair(b, i));//r树插入外包围矩形 i为索引
// }DBox b1(DPoint(0.0f, 0.0f), DPoint(1.0f, 1.0f));rtree.insert(std::make_pair(b1, 0));//r树插入外包围矩形 i为索引DBox b2(DPoint(-1.0f, -1.0f), DPoint(0.0f, 0.0f));rtree.insert(std::make_pair(b2, 1));//r树插入外包围矩形 i为索引DBox b3(DPoint(0.0f, 0.0f), DPoint(1.5f, 1.5f));rtree.insert(std::make_pair(b3, 2));//r树插入外包围矩形 i为索引//查询与矩形相交的矩形索引DBox query_box(DPoint(-0.1f, -0.1f), DPoint(1.2f, 1.2f));std::vector<Value> result_s;/*--------------------------------------------------------------------------------------**//*** 支持ring和polygon Commented by Simon.Zou on 5/2021+---------------+---------------+---------------+---------------+---------------+-----------*/using namespace boost::assign;typedef boost::geometry::model::d2::point_xy<double> point_xy;// Create points to represent a 5x5 closed polygon.std::vector<point_xy> points;points += point_xy(0.1, 0.1), point_xy(0.1, 5),point_xy(2.5, 5),point_xy(5, 2.5),point_xy(5, 0.1),point_xy(0.1, 0.1);// Create a polygon object and assign the points to it.boost::geometry::model::polygon<point_xy> polygon;DPolygon p;boost::geometry::assign_points(p, points);rtree.query(bgi::intersects(p), std::back_inserter(result_s));//查找5个离点最近的索引std::vector<Value> result_n;rtree.query(bgi::nearest(DPoint(0, 0), 5), std::back_inserter(result_n));//显示值std::cout << "spatial query box:" << std::endl;std::cout << bg::wkt<DBox>(query_box) << std::endl;std::cout << "spatial query result:" << std::endl;//BOOST_FOREACH(Value const& v, result_s)// std::cout << bg::wkt<DBox>(v.first) << " - " << v.second << std::endl;std::cout << "knn query point:" << std::endl;std::cout << bg::wkt<DPoint>(DPoint(0, 0)) << std::endl;std::cout << "knn query result:" << std::endl;//BOOST_FOREACH(Value const& v, result_n)// std::cout << bg::wkt<DBox>(v.first) << " - " << v.second << std::endl;
}//创建多边形
void boost_test5()
{typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> Point;typedef boost::geometry::model::polygon<Point, false, false> Polygon; // ccw, open polygon//创建多边形Polygon p;for (float a = 0; a < 6.28316f; a += 1.04720f){float x = int(10 * ::cos(a))*0.1f;float y = int(10 * ::sin(a))*0.1f;p.outer().push_back(Point(x, y));}
}//创建多边形
void boost_test6()
{namespace bg = boost::geometry;typedef bg::model::d2::point_xy<double> DPoint; //双精度的点typedef bg::model::segment<DPoint> DSegment; //线段typedef bg::model::linestring<DPoint> DLineString; //多段线typedef bg::model::box<DPoint> DBox; //矩形//这里的ring就是我们通常说的多边形闭合区域(内部不存在缕空),模板参数为true,表示顺时针存储点,为false,表示逆时针存储点,坐标系为正常向上向右为正的笛卡尔坐标系typedef bg::model::ring<DPoint, false> DRing; //环typedef bg::model::polygon<DPoint, false> DPolygon; //多边形#define A_PI 3.141592653589793238462643383279502884197//创建点DPoint pt1(0, 0), pt2(10, 10);//创建线段DSegment ds;ds.first = pt1;ds.second = pt2;//创建多段线DLineString dl;dl.push_back(DPoint(0, 0));dl.push_back(DPoint(15, 8));dl.push_back(DPoint(8, 13));dl.push_back(DPoint(13, 16));//创建矩形DBox db(pt1, pt2);//创建环DRing dr;dr.push_back(DPoint(0, 0));dr.push_back(DPoint(1, 2));dr.push_back(DPoint(3, 4));dr.push_back(DPoint(5, 6));//创建多边形DPolygon p;for (double a = 0; a < 2 * A_PI; a += 2 * A_PI / 18){double x = ::cos(a)*10.0f;double y = ::sin(a)*10.0f;p.outer().push_back(DPoint(x, y));}
}/*
如何让rtree用自己的数据。
看来最重要的操作是用indexable来让rtree知道,如何在你的结构体里得到point?
https://stackoverflow.com/questions/64179718/storing-or-accessing-objects-in-boost-r-tree
ou can store any type in a rtree, you just have to tell Boost how to get the coordinates out.So the first step is to make a type with both a index and point:struct CityRef {
size_t index;
point location;
};You can specialize boost::geometry::index::indexable to give Boost a way to find the point you've put in there:template <>
struct bgi::indexable<CityRef>
{
typedef point result_type;
point operator()(const CityRef& c) const { return c.location; }
};Then you can use your type in place of point when declaring your rtree:typedef bgi::rtree< CityRef, bgi::linear<16> > rtree_t;And when you iterate, the iterator will refer to your type instead of point:for ( rtree_t::const_query_iterator
it = rtree.qbegin(bgi::nearest(pt, 100)) ;
it != rtree.qend() ;
++it )
{
// *it is a CityRef, do whatever you want
}Here is a demo using that example with another type: https://godbolt.org/z/zT3xcf*/namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<double, 2, bg::cs::cartesian> boostPoint2d;
struct CityRef {size_t index;double index2;boostPoint2d location;//rtree在插入数据以及检索时,没走到这个函数,说明rtree内部是用指针的
// CityRef& operator = (const CityRef& r)
// {
// index = r.index;
// index2 = r.index2;
// location = r.location;
// return *this;
// }//rtree在插入数据以及检索时,没走到这个函数
// bool operator == (const CityRef& r) const
// {
// bool b1 = index == r.index;
// bool b2 = index2 == r.index2;
// bool b3 = (location.get<0>() == r.location.get<0>() &&
// location.get<1>() == r.location.get<1>());
//
// if (b1&&b2&&b3)
// return true;
//
// return false;
// }
};template <>
struct bgi::indexable<CityRef>
{typedef boostPoint2d result_type; //这个不能缺少//boostPoint2d operator()(const CityRef& c) const { return c.location; }const boostPoint2d& operator()(const CityRef& c) const { return c.location; }
};struct BoostTest7
{int DoTest() {typedef CityRef value;typedef bgi::rtree< value, bgi::linear<16> > rtree_t;// create the rtree using default constructorrtree_t rtree;// create some valuesfor ( double f = 0 ; f < 10 ; f += 1 ){CityRef data;data.index = (static_cast<size_t>(f));data.index2 = f + 1;data.location.set<0>(f);data.location.set<1>(f);// insert new valuertree.insert(data);//rtree.insert({ static_cast<size_t>(f), f + 1,{ f, f } });}// query pointboostPoint2d pt(5.1, 5.1);// iterate over nearest Values//根据距离从近到远/*index=5, index2=6.000000, (5.000000, 5.000000), distance=0.141421index=6, index2=7.000000, (6.000000, 6.000000), distance=1.272792index=4, index2=5.000000, (4.000000, 4.000000), distance=1.555635index=7, index2=8.000000, (7.000000, 7.000000), distance=2.687006break!*//*另外,这种写法的原因,是为了在满足数据条件后可以直接break。https://www.py4u.net/discuss/75145https://www.boost.org/doc/libs/1_55_0/libs/geometry/doc/html/geometry/spatial_indexes/queries.html#geometry.spatial_indexes.queries.breaking_or_pausing_the_queryBreaking or pausing the queryThe query performed using query iterators may be paused and resumed if needed, e.g. when the query takes too long, or stopped at some point, e.g when all interesting values were gathered.for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;it != tree.qend() ; ++it ){// do something with valueif ( has_enough_nearest_values() )break;}*/for ( rtree_t::const_query_iteratorit = rtree.qbegin(bgi::nearest(pt, 100)) ;it != rtree.qend() ;++it ){double d = bg::distance(pt, it->location);///*可以修改除了point之外的数据*/CityRef& xx = const_cast<CityRef&>(*it);xx.index2 = 10;//std::cout << "index=" << it->index << ", " << bg::wkt(it->location) << ", distance= " << d << std::endl;wprintf(L"\n index=%d, index2=%f, (%f, %f), distance=%f", it->index , it->index2,it->location.get<0>() ,it->location.get<1>(), d );// break if the distance is too bigif ( d > 2 ){std::cout << "break!" << std::endl;break;}}return 0;
}};
void boostTest7()
{BoostTest7 o;o.DoTest();}

相关文章:
C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型
用自己定义的数据结构作为rtree的key。 // rTree的key struct OverlapKey {using BDPoint boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian>; //双精度的点using MyRTree boost::geometry::index::rtree<OverlapKey, boost::geometry::in…...
让空间计算触手可及,VR手套何以点石成金?
引言 如何让一位母亲与她去世的小女儿“重逢”?韩国MBC电视台《I Met You》节目实现了一个“不可能”心愿。 在空旷的绿幕中,母亲Jang Ji-sung透过VR头显,看到了三年前因白血病去世的女儿Nayeon。当她伸出双手,居然能摸到女儿的…...
穿越数据迷宫:C++哈希表的奇幻旅程
文章目录 前言📔一、unordered系列关联式容器📕1.1 unordered 容器概述📕1.2 哈希表在 unordered 容器中的实现原理📕1.3 unordered 容器的特点 📔二、unordered_set 和 unordered_map 的基本操作📕2.1 un…...
SMT32 智能环境监测系统 嵌入式初学者课堂小组作业
一、应用知识 1,开发语言:C语言 2,开发工具:Keil uVision5、Setup_JLinkARM_V415e 3,开发平台:XCOM V2.0 4,开发知识:温湿度传感DHT11、STM32F4xx中文参考手册 5,文…...
20241114给荣品PRO-RK3566开发板刷Rockchip原厂的Android13下适配RJ45以太网卡
20241114给荣品PRO-RK3566开发板刷Rockchip原厂的Android13下适配RJ45以太网卡 2024/11/14 15:44 缘起:使用EVB2的方案,RJ45加进去怎么也不通。 实在没有办法,只能将荣品的SDK:rk-android13-20240713.tgz 解压缩,编译之…...
JVM这个工具的使用方法
JVM(Java虚拟机)是Java程序运行的基础环境,它提供了内存管理、线程管理和性能监控等功能。吃透JVM诊断方法,可以帮助开发者更有效地解决Java应用在运行时遇到的问题。以下是一些常见的JVM诊断方法: 使用JConsole: JCon…...
创建型设计模式与面向接口编程
创建型设计模式(Creational Patterns)的主要目的之一就是帮助实现面向接口编程,避免直接创建实现类的实例。通过这些模式,可以将对象的创建过程封装起来,使得客户端代码不需要知道具体的实现类,从而提高代码…...
算法每日双题精讲——滑动窗口(长度最小的子数组,无重复字符的最长子串)
🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟 别再犹豫了!快来订阅我们的算法每日双题精讲专栏,一起踏上算法学习的精彩之旅吧!💪…...
1.7 JS性能优化
从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST? > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放? 大流量 > 多个…...
STL - vector的使用和模拟实现
目录 一:vector的构造函数 二:vector的迭代器 三vector的空间增长问题 四:vector 增删查改接口 五:vector的模拟实现 (一)一些简单接口的实现: (二)一些复杂接口的…...
《鸿蒙生态:开发者的机遇与挑战》
一、引言 在当今科技飞速发展的时代,操作系统作为连接硬件与软件的核心枢纽,其重要性不言而喻。鸿蒙系统的出现,为开发者带来了新的机遇与挑战。本文将从开发者的角度出发,阐述对鸿蒙生态的认知和了解,分析鸿蒙生态的…...
【C++融会贯通】二叉树进阶
目录 一、内容说明 二、二叉搜索树 2.1 二叉搜索树概念 2.2 二叉搜索树操作 2.2.1 二叉搜索树的查找 2.2.2 二叉搜索树的插入 2.2.3 二叉搜索树的删除 2.3 二叉搜索树的实现 2.3.1 二叉搜索树的节点设置 2.3.2 二叉搜索树的查找函数 2.3.2.1 非递归实现 2.3.2.2 递…...
使用python-Spark使用的场景案例具体代码分析
使用场景 1. 数据批处理 • 日志分析:互联网公司每天会产生海量的服务器日志,如访问日志、应用程序日志等。Spark可以高效地读取这些日志文件,对数据进行清洗(例如去除无效记录、解析日志格式)、转换(例如…...
如何查看本地的个人SSH密钥
1.确保你的电脑上安装了 Git。 你可以通过终端或命令提示符输入以下命令来检查: git --version 如果没有安装,请前往 Git 官网 下载并安装适合你操作系统的版本。 2.查找SSH密钥 默认情况下,SSH密钥存储在你的用户目录下的.ssh文件夹中。…...
本人认为 写程序的三大基本原则
1. 合法性 定义:合法性指的是程序必须遵守法律法规和道德规范,不得用于非法活动。 建议: 了解法律法规:在编写程序之前,了解并遵守所在国家或地区的法律法规,特别是与数据隐私、版权、网络安…...
A030-基于Spring boot的公司资产网站设计与实现
🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 赠送计算机毕业设计600…...
React Hooks 深度解析与实战
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 React Hooks 深度解析与实战 React Hooks 深度解析与实战 React Hooks 深度解析与实战 引言 什么是 Hooks? 定义 为什么需要 Ho…...
#渗透测试#SRC漏洞挖掘#蓝队基础之网络七层杀伤链04 终章
网络杀伤链模型(Kill Chain Model)是一种用于描述和分析网络攻击各个阶段的框架。这个模型最初由洛克希德马丁公司提出,用于帮助企业和组织识别和防御网络攻击。网络杀伤链模型将网络攻击过程分解为多个阶段,每个阶段都有特定的活…...
计算机毕业设计Python+大模型农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
爬虫补环境案例---问财网(rpc,jsdom,代理,selenium)
目录 一.环境检测 1. 什么是环境检测 2.案例讲解 二 .吐环境脚本 1. 简介 2. 基础使用方法 3.数据返回 4. 完整代理使用 5. 代理封装 6. 封装所有使用方法 jsdom补环境 1. 环境安装 2. 基本使用 3. 添加参数形式 Selenium补环境 1. 简介 2.实战案例 1. 逆向目…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
