使用二分查找法找出给定点距离给定点集合距离最近的点
1、场景描述
给定点Point A (x,y)和 直线点集合 Points [(x1,y1),(x2,y2),(x3,y3),(x4,y4),(x5,y5)......],计算出集合中距离点A最近的一个点 (如果集合中的两个点距离A点最近且相等,则只取其中一个)
2、代码,
LatLngXY.java
package com.example.demo.letcode;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LatLngXY {private Double x;private Double y;
}
3、二分算法代码
BinarySearch.java
package com.example.demo.letcode;import com.google.common.collect.Lists;
import com.google.common.util.concurrent.AtomicDouble;import java.util.List;public class BinarySearch {/*** 二分查找算法** @param latLngList 给定点集合* @param latLng 给定点* @param atomicDouble 存储最小距离* @return*/public static LatLngXY binarySearch(List<LatLngXY> latLngList, LatLngXY latLng, AtomicDouble atomicDouble) {if (latLngList.size() == 1) {return latLngList.get(0);}//int middle = latLngList.size() / 2;LatLngXY middleLatLng = latLngList.get(middle);List<LatLngXY> left = latLngList.subList(0, middle);List<LatLngXY> right = latLngList.subList(middle, latLngList.size());//计算中间点距离double dis = distatce(middleLatLng, latLng);atomicDouble.set(dis);if (dis == 0) {//距离是0 点重合 直接返回return middleLatLng;} else {if (right.size() == 1) {//右侧 就一个元素 是中间元素已经对比过了//取左侧最后一个点LatLngXY leftLast = left.get(left.size() - 1);double leftdis = distatce(latLng, leftLast);if (leftdis == atomicDouble.get()) {return leftLast;}if (leftdis > atomicDouble.get()) {//中间点 距离小于左侧的return middleLatLng;}//左侧点距离小于当前中间点计算距离 且小于右侧点计算的距离 递归查找左侧if (leftdis < atomicDouble.get()) {atomicDouble.set(leftdis);return binarySearch(left, latLng, atomicDouble);}} else {//右侧多个元素//取左侧最后一个点LatLngXY leftLast = left.get(left.size() - 1);// 取右侧第二个点 没有则取第一个点LatLngXY rightSecond = right.get(1);double leftdis = distatce(latLng, leftLast);double rightDis = distatce(latLng, rightSecond);//正好中间就是距离最小的if (rightDis > atomicDouble.get() && leftdis > atomicDouble.get()) {return middleLatLng;}if (leftdis == atomicDouble.get()) {return leftLast;}if (rightDis == atomicDouble.get()) {return rightSecond;}//左侧点距离小于当前中间点计算距离 且小于右侧点计算的距离 递归查找左侧if (leftdis < atomicDouble.get() && leftdis < rightDis) {atomicDouble.set(leftdis);return binarySearch(left, latLng, atomicDouble);}//右侧点距离小于当前中间点计算距离 且小于左侧点计算的距离 递归查找右侧if (rightDis < atomicDouble.get() && rightDis < leftdis) {atomicDouble.set(rightDis);return binarySearch(right, latLng, atomicDouble);}}}return null;}/*** 计算两点之间距离** @param latLng1* @param latLng2* @return*/public static double distatce(LatLngXY latLng1, LatLngXY latLng2) {double x = latLng2.getX() - latLng1.getX();double y = latLng2.getY() - latLng1.getY();//平方相加double xy = Math.pow(x, 2) + Math.pow(y, 2);//开方return Math.sqrt(xy);}public static void main(String[] args) {List<LatLngXY> latLngList = Lists.newArrayList();LatLngXY lanLng1 = LatLngXY.builder().y(0D).x(1D).build();LatLngXY lanLng2 = LatLngXY.builder().y(0D).x(2D).build();LatLngXY lanLng3 = LatLngXY.builder().y(0D).x(3D).build();LatLngXY lanLng4 = LatLngXY.builder().y(0D).x(4D).build();LatLngXY lanLng5 = LatLngXY.builder().y(0D).x(5D).build();LatLngXY lanLng6 = LatLngXY.builder().y(0D).x(6D).build();LatLngXY lanLng7 = LatLngXY.builder().y(0D).x(7D).build();latLngList.add(lanLng1);latLngList.add(lanLng2);
// latLngList.add(lanLng3);latLngList.add(lanLng4);latLngList.add(lanLng5);latLngList.add(lanLng6);latLngList.add(lanLng7);LatLngXY lanLng81 = LatLngXY.builder().y(0D).x(3.5D).build();LatLngXY search1 = binarySearch(latLngList, lanLng81, new AtomicDouble(Double.MAX_VALUE));System.out.println(search1);// LatLngXY lanLng82 = LatLngXY.builder().y(0D)
// .x(1.0D).build();
// LatLngXY search2 = binarySearch(latLngList, lanLng82, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search2);
//
// LatLngXY lanLng83 = LatLngXY.builder().y(0D)
// .x(1.2D).build();
// LatLngXY search3 = binarySearch(latLngList, lanLng83, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search3);
//
// LatLngXY lanLng84 = LatLngXY.builder().y(0D)
// .x(1.8D).build();
// LatLngXY search4 = binarySearch(latLngList, lanLng84, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search4);
//
// LatLngXY lanLng85 = LatLngXY.builder().y(0D)
// .x(2.0D).build();
// LatLngXY search5 = binarySearch(latLngList, lanLng85, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search5);
//
// LatLngXY lanLng86 = LatLngXY.builder().y(0D)
// .x(2.2D).build();
// LatLngXY search6 = binarySearch(latLngList, lanLng86, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search6);
//
// LatLngXY lanLng87 = LatLngXY.builder().y(0D)
// .x(2.6D).build();
// LatLngXY search7 = binarySearch(latLngList, lanLng87, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search7);
//
// LatLngXY lanLng88 = LatLngXY.builder().y(0D)
// .x(3.0D).build();
// LatLngXY search8 = binarySearch(latLngList, lanLng88, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search8);
//
// LatLngXY lanLng89 = LatLngXY.builder().y(0D)
// .x(3.2D).build();
// LatLngXY search9 = binarySearch(latLngList, lanLng89, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search9);
//
// LatLngXY lanLng810 = LatLngXY.builder().y(0D)
// .x(3.8D).build();
// LatLngXY search10 = binarySearch(latLngList, lanLng810, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search10);
//
// LatLngXY lanLng811 = LatLngXY.builder().y(0D)
// .x(4.0D).build();
// LatLngXY search11 = binarySearch(latLngList, lanLng811, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search11);
//
// LatLngXY lanLng812 = LatLngXY.builder().y(0D)
// .x(4.2D).build();
// LatLngXY search12 = binarySearch(latLngList, lanLng812, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search12);
//
// LatLngXY lanLng813 = LatLngXY.builder().y(0D)
// .x(4.6D).build();
// LatLngXY search13 = binarySearch(latLngList, lanLng813, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search13);
//
// LatLngXY lanLng814 = LatLngXY.builder().y(0D)
// .x(5.0D).build();
// LatLngXY search14 = binarySearch(latLngList, lanLng814, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search14);
//
// LatLngXY lanLng815 = LatLngXY.builder().y(0D)
// .x(5.2D).build();
// LatLngXY search15 = binarySearch(latLngList, lanLng815, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search15);
//
// LatLngXY lanLng816 = LatLngXY.builder().y(0D)
// .x(5.8D).build();
// LatLngXY search16 = binarySearch(latLngList, lanLng816, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search16);
//
// LatLngXY lanLng817 = LatLngXY.builder().y(0D)
// .x(6.0D).build();
// LatLngXY search17 = binarySearch(latLngList, lanLng817, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search17);
//
// LatLngXY lanLng818 = LatLngXY.builder().y(0D)
// .x(6.2D).build();
// LatLngXY search18 = binarySearch(latLngList, lanLng818, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search18);
//
// LatLngXY lanLng819 = LatLngXY.builder().y(0D)
// .x(6.8D).build();
// LatLngXY search19 = binarySearch(latLngList, lanLng819, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search19);
//
//
// LatLngXY lanLng820 = LatLngXY.builder().y(0D)
// .x(7.0D).build();
// LatLngXY search20 = binarySearch(latLngList, lanLng820, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search20);
//
//
// LatLngXY lanLng821 = LatLngXY.builder().y(0D)
// .x(7.6D).build();
// LatLngXY search21 = binarySearch(latLngList, lanLng821, new AtomicDouble(Double.MAX_VALUE));
// System.out.println(search21);}}
相关文章:
使用二分查找法找出给定点距离给定点集合距离最近的点
1、场景描述 给定点Point A (x,y)和 直线点集合 Points [(x1,y1),(x2,y2),(x3,y3),(x4,y4),(x5,y5)......],计算出集合中距离点A最近的一个点 (如果集合中的两个点距离A点最近且相等,则只取其中一个) 2、代码&#x…...
国标GB28181协议平台Liveweb:搭建建筑工地无线视频联网监控系统方案
随着科技高速发展,视频信号经过数字压缩,通过互联网宽带或者移动4G网络传递,可实现远程视频监控功能。将这一功能运用于施工现场安全管理,势必会大大提高管理效率,提升监管层次。而这些,通过Liveweb监控系统…...
构建MacOS应用小白教程(打包 签名 公证 上架)
打包 在package.json中,dependencies会被打进 Electron 应用的包里,而devDependencies则不会,所以必要的依赖需要放到dependencies中。files中定义自己需要被打进 Electron 包里的文件。以下是一个完整的 mac electron-builder的配置文件。 …...
Nginx 双向链表 ngx_queue_t
目录 一、基本概述 二、数据结构 三、接口描述与实现 1、相关宏接口 2、ngx_queue_middle 3、ngx_queue_sort 四、使用案例 整理自 nginx 1.9.2 源码 和 《深入理解 Nginx:模块开发与架构解析》 一、基本概述 双向链表的优势是可以快速进行数据插入、删除与…...
【vue】npm install 报错 python2 Error: not found: python2
如图所示,vue项目在下载依赖的时候报错找不到python2,有网友通过下载python2.7并配置环境变量解决了,这里有两个其他自测可用的方式,供各位作为参考。 报错的主要原因是因为【sass-loader】【node-sass】这两个依赖跟nodejs版本有…...
CS 144 check3: the TCP sender
Lecture Notes 略 Exercises 现在,在check3中,您将实现连接的另一边。 TCPSender是一种工具,它从出站字节流转换为将成为不可靠数据报的有效负载的段。 TCP sender的任务是确保receiver至少收到每个bytes一次。任务: 1、跟踪…...
Deepin/Linux clash TUN模式不起作用,因网关导致的问题的解决方案。
网关导致的问题的解决方案 查看路由 ip route寻找默认路由 默认路由应当为Mihomo default dev Mihomo scope link 如果不是,则 sudo ip route add default dev Mihomo在clash TUN开关状态发生变化时,Mihomo网卡会消失,所以提示找不到网卡…...
Tomato 靶机(通关攻略)
点击开启靶机 去kali终端输入 arp-scan -l //扫描靶机IP 扫出靶机IP192.168.131.171 第一步:信息收集 端口扫描 nmap -p- 192.168.131.171 敏感目录扫描 dirb http://192.168.131.171 总结: IP:192.168.168.131 开放端口:2…...
服务器被入侵登录不上怎么办?
在数字化时代,服务器作为数据存储与业务运行的核心载体,其安全性直接关系到企业的生死存亡。然而,随着网络攻击手段的不断升级,服务器被入侵的事件屡见不鲜,导致系统瘫痪、数据泄露等严重后果。当您发现自己的服务器被…...
达梦官方工具 SQLark数据迁移(oracle->达梦数据库)
应国产化需求需要,需将系统中涉及的各中间件替换成国产中间件,此文介绍了从Oracle迁移数据至达梦dm8的步骤,该文在windos环境下已验证测试过 1 SQLark介绍 SQLark是一款专为信创应用开发者设计的数据库开发和管理工具。它支持快速查询、创建和管理多种类型的数据库系统…...
redis数据类型:list
list 的相关命令配合使用的应用场景: 栈和队列:插入和弹出命令的配合,亦可实现栈和队列的功能 实现哪种数据结构,取决于插入和弹出命令的配合,如左插右出或右插左出:这两种种方式实现先进先出的数据结构&a…...
.NET周刊【12月第2期 2024-12-08】
国内文章 终于解决了.net在线客服系统总是被360误报的问题(对软件进行数字签名) https://www.cnblogs.com/sheng_chao/p/18581139 升讯威在线客服与营销系统由.net core和WPF开发,旨在开放、开源、共享。开发者为解决360与其他国产管家的误…...
C#—扩展方法
扩展方法 扩展方法是C#中一种特殊的静态方法,它定义在一个静态类中,但是可以像实例方法一样被调用,使得代码看起来更为直观和易于阅读。扩展方法允许你在不修改原始类的情况下,添加新的方法到现有的类型中。 有↓箭头的是扩展方…...
金碟中间件-AAS-V10.0安装
金蝶中间件AAS-V10.0 AAS-V10.0安装 1.解压AAS-v10.0安装包 unzip AAS-V10.zip2.更新license.xml cd /root/ApusicAS/aas# 这里要将license复制到该路径 [rootvdb1 aas]# ls bin docs jmods lib modules templates config domains …...
sql server 查询对象的修改时间
sql server 不能查询索引的最后修改时间,可以查询表,存储过程,函数,pk 的最后修改时间使用以下语句 select * from sys.all_objects ob order by ob.modify_date desc 但可以参考一下统计信息的最后修改时间,因为索…...
Qt之串口设计-线程实现(十二)
Qt开发 系列文章 - Serial-port(十二) 目录 前言 一、SerialPort 二、实现方式 1.创建类 2.相关功能函数 3.用户使用 4.效果演示 5.拓展应用-实时刷新 总结 前言 Qt作为一个跨平台的应用程序开发框架,在串口编程方面提供了方便易用…...
探索 Seaborn Palette 的奥秘:为数据可视化增色添彩
一、引言 在数据科学的世界里,视觉传达是不可或缺的一环。一个好的数据可视化不仅能传递信息,还能引发共鸣。Seaborn 是 Python 中一款广受欢迎的可视化库,而它的调色板(palette)功能,则为我们提供了调配绚…...
Linux创建普通用户和修改主机名
创建修改用户名和用户组 工作组相关命令 功能命令说明切换用户su username注销用户logout新建用户adduser username 创建用户并分配到用户组useradd -g test username 设置用户密码passwd username查看某一用户w username查看登录用户w查看登陆用户并显示IPwho查看登录历史…...
在 Spring Boot 3 中实现基于角色的访问控制
基于角色的访问控制 (RBAC) 是一种有价值的访问控制模型,可增强安全性、简化访问管理并提高效率。它在管理资源访问对安全和运营至关重要的复杂环境中尤其有益。 我们将做什么 我们有一个包含公共路由和受限路由的 Web API。受限路由需要数据库中用户的有效 JWT。 现在用户…...
二八(vue2-04)、scoped、data函数、父子通信、props校验、非父子通信(EventBus、provideinject)、v-model进阶
1. 组件的三大组成部分(结构/样式/逻辑) 1.1 scoped 样式冲突 App.vue <template><!-- template 只能有一个根元素 --><div id"app"><BaseOne></BaseOne><BaseTwo></BaseTwo></div> </template><script…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...
职坐标物联网全栈开发全流程解析
物联网全栈开发涵盖从物理设备到上层应用的完整技术链路,其核心流程可归纳为四大模块:感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性,例如传感器选型需平衡精度与…...
