当前位置: 首页 > news >正文

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手套何以点石成金?

引言 如何让一位母亲与她去世的小女儿“重逢”&#xff1f;韩国MBC电视台《I Met You》节目实现了一个“不可能”心愿。 在空旷的绿幕中&#xff0c;母亲Jang Ji-sung透过VR头显&#xff0c;看到了三年前因白血病去世的女儿Nayeon。当她伸出双手&#xff0c;居然能摸到女儿的…...

穿越数据迷宫:C++哈希表的奇幻旅程

文章目录 前言&#x1f4d4;一、unordered系列关联式容器&#x1f4d5;1.1 unordered 容器概述&#x1f4d5;1.2 哈希表在 unordered 容器中的实现原理&#x1f4d5;1.3 unordered 容器的特点 &#x1f4d4;二、unordered_set 和 unordered_map 的基本操作&#x1f4d5;2.1 un…...

SMT32 智能环境监测系统 嵌入式初学者课堂小组作业

一、应用知识 1&#xff0c;开发语言&#xff1a;C语言 2&#xff0c;开发工具&#xff1a;Keil uVision5、Setup_JLinkARM_V415e 3&#xff0c;开发平台&#xff1a;XCOM V2.0 4&#xff0c;开发知识&#xff1a;温湿度传感DHT11、STM32F4xx中文参考手册 5&#xff0c;文…...

20241114给荣品PRO-RK3566开发板刷Rockchip原厂的Android13下适配RJ45以太网卡

20241114给荣品PRO-RK3566开发板刷Rockchip原厂的Android13下适配RJ45以太网卡 2024/11/14 15:44 缘起&#xff1a;使用EVB2的方案&#xff0c;RJ45加进去怎么也不通。 实在没有办法&#xff0c;只能将荣品的SDK&#xff1a;rk-android13-20240713.tgz 解压缩&#xff0c;编译之…...

JVM这个工具的使用方法

JVM&#xff08;Java虚拟机&#xff09;是Java程序运行的基础环境&#xff0c;它提供了内存管理、线程管理和性能监控等功能。吃透JVM诊断方法&#xff0c;可以帮助开发者更有效地解决Java应用在运行时遇到的问题。以下是一些常见的JVM诊断方法&#xff1a; 使用JConsole: JCon…...

创建型设计模式与面向接口编程

创建型设计模式&#xff08;Creational Patterns&#xff09;的主要目的之一就是帮助实现面向接口编程&#xff0c;避免直接创建实现类的实例。通过这些模式&#xff0c;可以将对象的创建过程封装起来&#xff0c;使得客户端代码不需要知道具体的实现类&#xff0c;从而提高代码…...

算法每日双题精讲——滑动窗口(长度最小的子数组,无重复字符的最长子串)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#xff01;&#x1f4aa;…...

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST&#xff1f; > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放&#xff1f; 大流量 > 多个…...

STL - vector的使用和模拟实现

目录 一&#xff1a;vector的构造函数 二&#xff1a;vector的迭代器 三vector的空间增长问题 四&#xff1a;vector 增删查改接口 五&#xff1a;vector的模拟实现 &#xff08;一&#xff09;一些简单接口的实现&#xff1a; &#xff08;二&#xff09;一些复杂接口的…...

《鸿蒙生态:开发者的机遇与挑战》

一、引言 在当今科技飞速发展的时代&#xff0c;操作系统作为连接硬件与软件的核心枢纽&#xff0c;其重要性不言而喻。鸿蒙系统的出现&#xff0c;为开发者带来了新的机遇与挑战。本文将从开发者的角度出发&#xff0c;阐述对鸿蒙生态的认知和了解&#xff0c;分析鸿蒙生态的…...

【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. 数据批处理 • 日志分析&#xff1a;互联网公司每天会产生海量的服务器日志&#xff0c;如访问日志、应用程序日志等。Spark可以高效地读取这些日志文件&#xff0c;对数据进行清洗&#xff08;例如去除无效记录、解析日志格式&#xff09;、转换&#xff08;例如…...

如何查看本地的个人SSH密钥

1.确保你的电脑上安装了 Git。 你可以通过终端或命令提示符输入以下命令来检查&#xff1a; git --version 如果没有安装&#xff0c;请前往 Git 官网 下载并安装适合你操作系统的版本。 2.查找SSH密钥 默认情况下&#xff0c;SSH密钥存储在你的用户目录下的.ssh文件夹中。…...

本人认为 写程序的三大基本原则

1. 合法性 ‌定义‌&#xff1a;合法性指的是程序必须遵守法律法规和道德规范&#xff0c;不得用于非法活动。 ‌建议‌&#xff1a; ‌了解法律法规‌&#xff1a;在编写程序之前&#xff0c;了解并遵守所在国家或地区的法律法规&#xff0c;特别是与数据隐私、版权、网络安…...

A030-基于Spring boot的公司资产网站设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…...

React Hooks 深度解析与实战

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 React Hooks 深度解析与实战 React Hooks 深度解析与实战 React Hooks 深度解析与实战 引言 什么是 Hooks? 定义 为什么需要 Ho…...

#渗透测试#SRC漏洞挖掘#蓝队基础之网络七层杀伤链04 终章

网络杀伤链模型&#xff08;Kill Chain Model&#xff09;是一种用于描述和分析网络攻击各个阶段的框架。这个模型最初由洛克希德马丁公司提出&#xff0c;用于帮助企业和组织识别和防御网络攻击。网络杀伤链模型将网络攻击过程分解为多个阶段&#xff0c;每个阶段都有特定的活…...

计算机毕业设计Python+大模型农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

爬虫补环境案例---问财网(rpc,jsdom,代理,selenium)

目录 一.环境检测 1. 什么是环境检测 2.案例讲解 二 .吐环境脚本 1. 简介 2. 基础使用方法 3.数据返回 4. 完整代理使用 5. 代理封装 6. 封装所有使用方法 jsdom补环境 1. 环境安装 2. 基本使用 3. 添加参数形式 Selenium补环境 1. 简介 2.实战案例 1. 逆向目…...

零基础WordPress建站:可视化编辑器推荐(2026版-含下载)

&#x1f645;‍♀️ 零基础学WP建站&#xff0c;怕代码&#xff1f;怕复杂&#xff1f;怕翻车&#xff1f; 2026最新可视化编辑器实测合集来啦✨ 纯干货无链接&#xff0c;全程拖拽操作、所见即所得&#xff0c;小白也能轻松搭出专业网站&#xff0c;告别技术焦虑&#xff0c;…...

nlp_gte_sentence-embedding_chinese-large在软件测试用例生成中的应用

nlp_gte_sentence-embedding_chinese-large在软件测试用例生成中的应用 1. 引言 软件测试是确保产品质量的关键环节&#xff0c;但传统的手工编写测试用例方式往往效率低下且容易遗漏重要场景。测试工程师需要反复阅读需求文档&#xff0c;手动提取测试要点&#xff0c;这个过…...

【电赛实战利器】基于STM32F4与协方差修正的全数字锁相放大器设计与实测

1. 为什么你需要一个全数字锁相放大器&#xff1f; 在电子设计竞赛或者精密测量项目中&#xff0c;微弱信号检测总是让人头疼。想象一下&#xff0c;你要从一堆嘈杂的噪音中找出一个微弱的正弦波信号&#xff0c;就像在喧闹的菜市场里听清远处朋友的耳语。传统模拟锁相放大器需…...

STM32F103引脚功能全解析:从供电到通信接口的实战配置指南

STM32F103引脚功能全解析&#xff1a;从供电到通信接口的实战配置指南 在嵌入式系统开发中&#xff0c;STM32F103系列微控制器因其出色的性能和丰富的外设资源&#xff0c;成为众多开发者的首选。这款基于ARM Cortex-M3内核的MCU&#xff0c;不仅具备72MHz的主频&#xff0c;还…...

OpenClaw故障自愈方案:Qwen3-32B镜像异常重启监控

OpenClaw故障自愈方案&#xff1a;Qwen3-32B镜像异常重启监控 1. 问题背景与解决思路 上周我的OpenClaw自动化助手突然"罢工"了——原本应该定时执行的日报生成任务没有按时完成。排查后发现是底层Qwen3-32B模型服务因OOM异常退出。这种情况在长期运行的AI服务中并…...

力扣高频经典双题解:接雨水 + 无重复最长子串(思路 + 满分代码)

接雨水、无重复字符最长子串是面试高频、算法入门必刷的经典题&#xff0c;一道考动态规划预处理&#xff0c;一道考滑动窗口&#xff0c;都是数组 / 字符串题型里的核心套路。本篇把两道题的思路讲透、代码写清&#xff0c;新手也能一遍看懂&#xff0c;刷题效率直接拉满&…...

Vivado中OSD核报错全攻略:从IP_flow 19-167到BD 41-1030的解决方案

Vivado中OSD核报错全攻略&#xff1a;从IP_flow 19-167到BD 41-1030的解决方案 在FPGA开发过程中&#xff0c;Xilinx Vivado工具链的OSD&#xff08;On-Screen Display&#xff09;核是一个常用的视频处理IP&#xff0c;但开发者常会遇到各种报错问题。本文将深入解析从IP_flo…...

【数据结构实战】循环队列FIFO 特性生成六十甲子(天干地支纪年法),实现传统文化里的 “时间轮回”

前言天干地支纪年法是中国传统文化的重要组成部分&#xff0c;十天干与十二地支依次相配&#xff0c;组成六十甲子。本文将使用循环队列这一数据结构完成六十甲子的生成&#xff0c;严格遵循题目要求&#xff1a;定义两个循环队列&#xff0c;分别存储十天干、十二地支队列空则…...

I2CLCD驱动库:HD44780字符屏的I²C轻量级嵌入式适配方案

1. I2CLCD库概述&#xff1a;面向嵌入式系统的字符型LCD IC适配驱动I2CLCD是一个轻量级、可移植的C语言驱动库&#xff0c;专为将标准HD44780兼容的字符型LCD&#xff08;如1602、2004&#xff09;通过IC总线接入MCU而设计。其核心价值在于消除并行接口对GPIO资源的高占用&…...

在单细胞测序数据分析中,barcodes、features和matrix是三个最核心的基础文件,它们共同构成了所有分析的基石。

在GEO&#xff08;Gene Expression Omnibus&#xff09;数据库中下载单细胞数据时&#xff0c;最常见的数据存储和提供形式主要有以下四种类型&#xff1a;10x Genomics 标准格式&#xff08;最主流&#xff09;在GEO的数据集中&#xff0c;我们通常会找到一个包含以下三个核心…...