如何实现字符串转换函数,使排序结果为原字典序的逆序?
问题
给定一个长度未知、已按字典序排序的UTF-8字符串列表s₁、s₂、s₃……,能否实现一个字符串转换函数invert,使得列表中每个字符串经过该函数转换后,按字典序排序得到的结果与原排序的逆序一致?
示例代码如下:
function invert(s) { // TODO: what's here? return s; } const sample = ['', ' ', 'a', 'A', '@', '한','자', '한자', '자한']; const original = [...sample].sort((a, b) => { return a.localeCompare(b); }); const inverted = [...sample].sort((a, b) => { return invert(a).localeCompare(invert(b)); }); // 两者输出应一致 console.log('original', original); console.log('inverted.reverse', inverted.reverse());
解决方案
可以实现这个invert函数,核心思路是对字符串中每个字符的Unicode码点做镜像反转,让原本字典序靠前的字符转换后变为靠后,反之亦然。
实现代码
function invert(s) { return Array.from(s).map(char => { const code = char.codePointAt(0); // 用Unicode最大可表示码点减去当前字符码点,实现排序权重反转 return String.fromCodePoint(0x10FFFF - code); }).join(''); }
原理说明
- Unicode码点映射:UTF-8字符对应的Unicode码点范围是0到0x10FFFF,用最大值减去每个字符的码点,就能得到一个镜像码点。比如码点较小的
@(64)转换后会变成大码点字符,码点较大的한(54620)转换后会变成小码点字符。 - 排序逻辑反转:当所有字符都完成这种反转后,
invert(a).localeCompare(invert(b))的计算结果等价于b.localeCompare(a),这就使得转换后的字符串排序结果,恰好是原排序的逆序。
效果验证
将上述invert函数代入示例代码后,original和inverted.reverse()的输出会完全一致,满足需求。
内容的提问来源于stack exchange,提问作者Code
相关产品推荐
相关产品推荐

