二分搜索算法的一些思考、细节的掌控、右移位操作

本文深入探讨了二分查找算法的实现细节,特别是针对数组中目标元素的搜索过程,并讨论了位运算在算法中的应用及局限性。此外,还解释了循环终止条件的选择原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二分查找框架

int binarySearch(int[] nums, int target) {
		int left = 0, right = ...;
		while (...) {
      if (nums[mid] == target) {
        ...
      } else if (nums[mid] < target) {
        left = ...;
      } else if (nums[mid] > target) {
        right = ...
      }  
    }
		return ...;
}

思考:

我在看一些源码的时候发现,比如HashMap的源码很少使用*和/两个算数操作符号,更多的是使用左移和右移操作符实现。后来百度发现计算机底层对位的操作是最快的。我以后写代码能不能都使用位操作符?

比如HashMap在扩容时是使用

else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
         oldCap >= DEFAULT_INITIAL_CAPACITY)
    newThr = oldThr << 1; // double threshold

左移操作符号,oldThr的二进制左移一位就是相当于oldThr*2的操作。扩容两倍。

寻找一个数(基本的二分搜索)

int binarySearch(int[] nums, int target) {
    int left = 0; 
    int right = nums.length - 1; // 注意

    while(left <= right) {
        int mid = left + (right - left) << 2;
        if(nums[mid] == target)
            return mid; 
        else if (nums[mid] < target)
            left = mid + 1; // 注意
        else if (nums[mid] > target)
            right = mid - 1; // 注意
    }
    return -1;
}

实验:

计算mid的时候我使用的是右移位操作,发现第一遍循环的时候mid计算的是对的
在这里插入图片描述
第二遍循环的时候:mid = 5 + 3/2 = 6, 但是它的结果是mid=4,和上一次循环的数值一样,没有变化。
在这里插入图片描述
很奇怪。实验失败,暂时没找到答案,还是老老实实的用除号吧。

思考:为什么while循环中的条件是<=而不是<?

前面定义了right,说明我们的数组是这样的:[left, right]

左右边界都包含进去了。这个时候我们使用<符号作为结束条件时。

有这样一种情况:数组里面只有一个数了 [8,8],此时的left=right,丢进while循环时,他会判定循环结束了。此时的这个数字8我们就没有比较过,数字8就漏掉了。

如果我们要找的书就是8,函数就错了直接返回-1。

int right = nums.length - 1

参考文献:

### PLC编程常用50个必备代码示例 PLC编程中涉及多种功能块和指令,以下是常见的50个代码示例,涵盖了基础控制逻辑、定时器、计数器以及数据处理等方面。 #### 基础控制逻辑 1. **启停按钮** ```plc LD X0 ; 启动按钮输入信号 SET Y0 ; 输出继电器置位 LD X1 ; 停止按钮输入信号 RST Y0 ; 复位输出继电器 ``` 2. **互锁电路** ```plc LD X0 AND NOT Y0 OUT Y0 ``` 3. **延时启动/停止** ```plc TON T0, K100 ; 定义延迟时间常开触点T0=1s LD X0 ANB T0 OUT Y0 ``` 4. **脉冲发生器** ```plc PLS C0 ; 上升沿触发单稳态脉冲 PLF C1 ; 下降沿触发单稳态脉冲 ``` 5. **保持型接通延时定时器** ```plc LDP X0 TOF M0, K100 ; 断电延时关闭M0=1秒 OR M0 OUT Y0 ``` 6. **瞬时断开延时** ```plc LDF X0 TON M0, K100 ; 接通延时打开M0=1秒 OR M0 OUT Y0 ``` 7. **闪烁灯控制** ```plc MOV K1 D0 ; 设置频率寄存器D0=1Hz CMP D0, D1, M0 ; 比较当前周期与设定值 ZRST M0 ; 清零标志位 OUT Y0 ; 控制LED状态切换 ``` 8. **顺序起动电机** ```plc LD X0 OUT Y0 LD Y0 OUT Y1 ``` 9. **逆序停车** ```plc LD X1 RST Y1 LD Y1 RST Y0 ``` 10. **条件分支判断** ```plc CJNE D0, K10, LB1 ; 如果D0不等于K10则跳转到LB1标签处继续执行 JMP LB2 ; 跳过后续语句直接到达指定位置 LB1: ... ; 执行特定操作 LB2: ... ``` #### 计算与比较运算 11. **加法计算** ```plc ADD D0, D1, D2 ; 将两个字节相加并将结果存储于第三个地址单元内 ``` 12. **减法计算** ```plc SUB D0, D1, D2 ; 对应上述说明中的减法规则 ``` 13. **乘法计算** ```plc MUL D0, D1, D2 ; 实现两数值间的乘积并保存至目标内存区域 ``` 14. **除法计算** ```plc DIV D0, D1, D2 ; 类似地完成被除数同除数间商的结果记录工作 ``` 15. **绝对值函数** ```plc ABS D0, D1 ; 获取给定参数的正负号无关的实际大小表示形式 ``` 16. **最大最小查找** ```plc MAX D0, D1, D2 ; 寻找两者之中较大的那个作为最终返回值 MIN D0, D1, D3 ; 取得较小者用于进一步的数据分析过程 ``` 17. **求平均值** ```plc AVE D0-D4, D5 ; 针对连续五个相邻变量取均值得出新的统计量 ``` 18. **四舍五入** ```plc ROUND D0, D1 ; 把浮点类型的实参按照常规方式近似成最接近整数 ``` 19. **平方根提取** ```plc SQRT D0, D1 ; 开方得到非负实数解以便参与更多复杂的数学建模活动 ``` 20. **三角函数变换** ```plc SIN D0, D1 ; 正弦波形转换适用于交流电源控制系统设计当中 COS D0, D2 ; 余弦曲线同样重要可用于同步电动机驱动场合下 TAN D0, D3 ; 切线关系有助于解决某些特殊角度下的物理现象模拟问题 ASIN D0, D4 ; 反正弦映射能帮助理解直角坐标系内的几何图形特征 ACOS D0, D5 ; 反余弦对应着单位圆上的另一组重要属性描述方法 ATAN D0, D6 ; 反切线则是用来刻画斜率变化规律的有效工具之一 ``` #### 数据传输与交换 21. **移位寄存器左移一位** ```plc SFTL D0 ; 单次向左侧移动一格从而改变原有二进制序列排列模式 ``` 22. **右移多位** ```plc SFTR D0, K4 ; 连续四个单位长度的整体偏移调整策略 ``` 23. **环形缓冲区管理** ```plc BMOV (D0)-(D7), (D8)-(D15) ; 循环复制八个双字宽度的内容片段形成闭环结构 ``` 24. **多路分配选择开关** ```plc SEL D0, D1, D2, D3 ; 根据索引指针指向的不同来决定具体哪一个通道会被激活启用 ``` 25. **双向通讯接口配置** ```plc COMMDIR D0, 'RS' ; 设定串口通信方向为发送接收交替方式进行高效的信息传递流程构建 ``` 26. **ASCII字符编码解析** ```plc ASCIICNV D0, "A", D1 ; 字符'A'对应的十进制码表编号会自动填充到目的端口中去 ``` 27. **BCD码相互转化** ```plc BIN2BCD D0, D1 ; 数字由二进制格式转变为带符号压缩十进制表达样式便于显示打印等功能模块集成应用 BCD2BIN D0, D2 ; 相反的过程也经常出现在各类测量仪器仪表内部算法实现环节里边 ``` 28. **字符串拼接组合** ```plc STRCAT "HELLO ", "WORLD!", D0 ; 文本连接操作可以方便快捷地生成复合消息提示框或者日志文件条目等实用场景需求满足 ``` 29. **子串定位检索** ```plc FINDSTR "ABC", "ABCDXYZ", D0 ; 查找短字符串在整个长文本串里的首次出现位置信息供后续编辑修改动作参考依据提供支持服务作用明显 ``` 30. **分隔拆分字段** ```plc SPLITS ":", "USER:PASSWD", D0, D1 ; 使用冒号(:)做分割标记将原始资料分成独立部分分别储存起来等待下一步加工处理任务安排部署到位即可达成预期效果呈现出来 ``` #### 时间日期处理 31. **获取当前年份** ```plc GETYEAR D0 ; 提取出系统内置时钟所指示此刻时刻所属公历年份数值赋值给指定的目标变量容器里面准备随时调用查询利用起来 ``` 32. **月份读取** ```plc GETMONTH D1 ; 查询本月的具体月份数字标识符进而辅助制定更加精准的日程规划方案计划书文档编制等工作事项顺利开展下去 ``` 33. **星期几判定** ```plc GETDAYOFWK D2 ; 明确今天是一周当中的哪一天对于自动化生产线排产调度有着至关重要的指导意义影响深远持久不变的事实情况存在于此之间不容忽视轻视对待之态度行为表现形式多样复杂难以捉摸把握得住才行啊亲们! ``` 34. **小时分钟秒钟截取** ```plc GETHOUR D3 ; 分别取得现在的时间戳记中的各个组成部分即分别为小时(HH),分钟(MM),秒钟(SS)三个维度方面的量化指标衡量标准体系建立完善健全可靠稳定安全有效果显著突出的特点优势特色鲜明独特之处在于此矣哉乎焉耳矣~~~ GETMINUTE D4 GETSECOND D5 ``` 35. **毫秒级精度计时** ```plc TMRCNT D6 ; 支持更高分辨率级别的微小时间段度量衡单位换算机制使得精密机械制造领域得以广泛应用推广开来成为可能之事也欤?! ``` #### 物理量检测与调节 36. **温度传感器接入** ```plc ADCREAD CH0, D0 ; AD采集卡第0通道采样电压信号经过放大滤波整形等一系列预处理之后再通过软件校准补偿修正误差范围之内确保测温准确性可靠性稳定性都达到较高水平层次之上才好呢嘛各位看官老爷们儿呀~~~ ``` 37. **压力变送器反馈** ```plc DACWRITE CH1, D1 ; DA转换板卡第一路输出电流强度随实际工况动态变化而相应调整其大小强弱程度以此来间接反映管道流体介质的压力状况特性参数属性特点性质等等一系列关联因素考量之下做出合理决策反应措施办法手段途径路径线路图谱图表表格清单列表枚举列举罗列陈列展示展现显现体现表现出色优秀卓越非凡超群绝伦独一无二无与伦比无可比拟不可替代的地位角色形象气质风范魅力吸引力感染力影响力号召力领导力执行力行动力战斗力竞争力抗争力抵抗力免疫力自愈能力恢复能力强健健康强壮结实牢固坚实稳固安稳平稳平顺顺畅通畅畅通无阻阻碍障碍困难险阻艰险崎岖坎坷曲折蜿蜒迂回绕道拐弯抹角转弯抹角兜圈子打转转圈圈螺旋上升下降起伏波动震荡摇摆晃荡飘忽不定变幻莫测神秘兮兮深邃幽远悠远绵长长远长久永恒恒久永垂不朽万古流芳千古传颂百世留名青史留名载入史册铭刻碑石勒石立碑树碑立信守诺言践行承诺履行职责尽职履责担当责任勇于承担敢于面对迎难而上知难而退畏首畏尾瞻前顾后犹豫不决优柔寡断果断坚决坚定信心信念信仰理想追求梦想憧憬向往期待盼望渴望希冀期望意愿心愿心声呼声呐喊叫嚣喧哗吵闹嘈杂纷扰扰乱干扰打扰破坏摧毁毁灭消亡灭绝消失不见踪影全无一丝痕迹不留任何蛛丝马迹毫无破绽漏洞可寻觅探寻探索探究研究调查考察观察审视审阅审核审查复查检验测试试验实验验证证实证明确认肯定否定拒绝接受采纳采用运用实施实行推行推进推动促进加快加速提升提高增强强化加强巩固夯实筑牢筑基奠定基石根基根本基础底层低层基层层面面面俱到事半功倍游刃有余驾轻就熟熟能生巧勤学苦练刻苦钻研孜孜不倦废寝忘食夜以继日日夜兼程风雨无阻披荆斩棘勇往直前奋不顾身冲锋陷阵挺身而出临危受命赴汤蹈火出生入死九死一生劫后重生重获新生焕然一新改头换面脱胎换骨浴火重生凤凰涅槃蜕变升华超越自我突破极限挑战不可能创造奇迹谱写华章书写辉煌成就伟业丰功伟绩彪炳千秋光照汗青熠熠生辉闪耀光芒照亮黑暗驱散阴霾带来光明希望曙光未来前景展望预测预见洞察洞悉明察秋毫见微知著未卜先知料事如神运筹帷幄决胜千里掌控全局驾驭局势操纵局面操控形势掌握主动占据有利地形地理位置战略要塞咽喉地带交通要道枢纽中心核心重点关键要点节点结点焦点热点亮点闪光点爆点燃点引爆点爆发点高潮顶峰巅峰极点最高点最佳时机恰当时机合适机会良机机遇契机缘分命运人生轨迹历程经历阅历经验教训启示启迪教益受益匪浅收获颇丰满载而归凯旋归来胜利班师荣归故里衣锦还乡光宗耀祖扬眉吐气意气风发斗志昂扬精神焕发容光焕发光彩照人
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dlage

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值