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. 逆向目…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
