如何实现适配字符串类型的二分搜索(Binary Search)?
解决字符串数组的二分搜索问题
咱们先拆解一下你遇到的问题,然后一步步修复:
问题根源
你的代码现在有几个关键问题导致字符串数组无法正常工作:
- 变量名错误:函数参数是
Array,但你在获取中间值的时候用了numberArray[middleIndex]——这个numberArray根本没定义!难怪测试字符串数组时会出问题(数字数组能运行可能是你测试时不小心把参数名改成了numberArray?)。 - 数组未排序:你测试字符串用的
['cat', 'dog', 'bird', 'fish']是乱序的,二分搜索的核心前提是数组必须预先有序,数字数组用的是有序集合所以能正常跑,字符串数组乱序的话肯定找不到目标值。 - 使用
splice修改原数组:splice会直接修改原数组,这种写法不仅有副作用,还容易在递归中出现边界问题,更好的做法是用slice获取子数组,不会改动原数组本身。
修复后的代码
我把这些问题都修复了,同时优化了变量名让代码更清晰:
function binarySearch(arr, key) { // 处理空数组的边界情况 if (arr.length === 0) return false; const middleIndex = Math.floor(arr.length / 2); const middleValue = arr[middleIndex]; // 找到目标值 if (middleValue === key) return true; // 目标值在右半部分,递归搜索 else if (middleValue < key) { return binarySearch(arr.slice(middleIndex + 1), key); } // 目标值在左半部分,递归搜索 else { return binarySearch(arr.slice(0, middleIndex), key); } }
测试验证
测试有序字符串数组
首先要确保字符串数组是按字典序排序的,比如:
// 先排序字符串数组 const sortedAnimals = ['bird', 'cat', 'dog', 'fish'].sort(); console.log(binarySearch(sortedAnimals, 'dog')); // 输出: true console.log(binarySearch(sortedAnimals, 'tiger')); // 输出: false
大小写注意事项
如果你的字符串有大小写混合,比如['Cat', 'bird', 'Dog'],直接排序会因为大写字母的Unicode码点比小写小,导致排序结果不符合预期。这时候可以统一转换成小写(或大写)再排序和比较:
function caseInsensitiveBinarySearch(arr, key) { // 先把数组按小写排序 const sortedArr = arr.map(str => str.toLowerCase()).sort(); const lowerKey = key.toLowerCase(); if (sortedArr.length === 0) return false; const middleIndex = Math.floor(sortedArr.length / 2); const middleValue = sortedArr[middleIndex]; if (middleValue === lowerKey) return true; else if (middleValue < lowerKey) { return caseInsensitiveBinarySearch(sortedArr.slice(middleIndex + 1), lowerKey); } else { return caseInsensitiveBinarySearch(sortedArr.slice(0, middleIndex), lowerKey); } } // 测试混合大小写 console.log(caseInsensitiveBinarySearch(['Cat', 'bird', 'Dog'], 'dog')); // 输出: true
额外说明
- 二分搜索的核心是有序数组,不管是数字还是字符串,只要数组是有序的,就能用相同逻辑处理——JavaScript中字符串可以直接用
<和>比较,本质是比较它们的Unicode码点,符合字典序规则。 - 用
slice代替splice可以避免修改原数组,让函数更纯粹,没有副作用。
内容的提问来源于stack exchange,提问作者PinPiguin
相关产品推荐
相关产品推荐

