You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS/TS实现6位小写字母串与序号双向映射 无数组二分查找方案

实现核心原理

这个序列本质是固定6位长度的26进制数序列,字符a到z刚好对应进制位取值0到25,序号从0开始计数时,和常规26进制与十进制的转换逻辑完全对齐,不需要生成任何实体数组,双向映射的时间复杂度为常数级O(6),性能极高。
总元素量26^6 = 308915776,数值远小于JS的最大安全整数(2^53-1),直接用普通Number类型计算即可,不需要引入BigInt。

具体实现步骤

1. 实现序号转字符串的映射函数

核心逻辑是把十进制序号逐位除以26取余数,从最低位(对应字符串最右侧字符)开始换算成对应字母,最后补全为6位长度即可。

const TOTAL = 26 ** 6;
const CHAR_CODE_A = 'a'.charCodeAt(0);

function indexToStr(index) {
  if (index < 0 || index >= TOTAL) {
    throw new RangeError('序号超出0~26^6-1的合法范围');
  }
  const result = [];
  let cur = index;
  for (let i = 0; i < 6; i++) {
    const remainder = cur % 26;
    result.unshift(String.fromCharCode(CHAR_CODE_A + remainder));
    cur = Math.floor(cur / 26);
  }
  return result.join('');
}

校验逻辑:indexToStr(0)返回aaaaaa,indexToStr(25)返回aaaaaz,indexToStr(26)返回aaaaba,indexToStr(TOTAL - 1)返回zzzzzz,符合序列要求。

2. 实现字符串转序号的映射函数

核心逻辑是把字符串每一位换算成0-25的数值,按照26进制的位权累加,得到对应的十进制序号。

function strToIndex(str) {
  if (typeof str !== 'string' || str.length !== 6 || !/^[a-z]{6}$/.test(str)) {
    throw new TypeError('输入必须是6位小写字母组成的字符串');
  }
  let index = 0;
  for (let i = 0; i < 6; i++) {
    const num = str.charCodeAt(i) - CHAR_CODE_A;
    index = index * 26 + num;
  }
  return index;
}

两个函数为严格双向映射,任意合法输入经过两次转换后会得到原值。

3. 实现无数组二分查找

有了双向映射能力后,不需要构建实体数组,直接用序号作为左右边界即可完成二分查找。JS原生字符串的字典序比较结果,和序号大小的比较结果完全一致,不需要额外写比较逻辑。

function searchTarget(target) {
  if (typeof target !== 'string' || target.length !== 6 || !/^[a-z]{6}$/.test(target)) {
    throw new TypeError('查找目标必须是6位小写字母组成的字符串');
  }
  let left = 0;
  let right = TOTAL - 1;
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    const midStr = indexToStr(mid);
    if (midStr === target) {
      return mid;
    } else if (midStr < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }
  // 全排列场景下所有合法输入必然存在,此处仅为逻辑兜底
  return -1;
}
性能与注意事项
  • 两个转换函数固定执行6次循环,单次执行耗时在纳秒级;二分查找最多迭代log2(308915776) ≈ 28次,Node.js环境下单次查找总耗时不到1毫秒,无额外内存占用,完全规避了生成3亿元素数组带来的内存溢出问题。
  • 若业务侧需要序号从1开始计数,只需要在两个转换函数的入参、返回值位置统一做+1/-1的偏移即可,核心逻辑不需要改动。
  • 必须加边界校验,避免非法入参导致计算结果偏差。

内容的提问来源于stack exchange,提问作者Michael Merjanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:57:22