首先这个问题是我在牛客网练算法题(具体题号:No.HJ26)的时候遇见的,也是困扰了我好久才解决,所以我打算写成博客的形式,给遇到类似问题的童鞋速度解决困扰。
一. 问题阐述
算法中需要对字符串里的英文字母不分大小写按字典顺序重新排列,特殊字符原位输出,例子如下:
- Type ——> epTy
- BabA ——> aABb
- By?e ——> Be?y
使用字符串A Famous Saying: Much Ado About Nothing (2012/8).
分别的输出情况:
- 在vscode里的Node.js环境下运行结果为:
- 之后粘到牛客网上的编辑器窗口里运行(Google V8 6.0.0环境)。显示没通过所有的测试用例,细看那个未通过的用例,我突然发现怎么输出结果和在vscode里不一样???
仔细比对后发现原来是字母相同的部分排列顺序有出入…啊…这…(ˉ▽ˉ;)…
二. 结论👇
Array.sort()
排序在v8引擎中可能会存在同值乱序的BUG:
具体的原因是因为Google v8引擎为了排序的高效性,针对不同数组长度采取了不同的排序策略:
数组长度在10以下用的是快速排序算法,和其他浏览器环境或者Node.js环境下的运行结果相同;超过10之后Google v8引擎就会调用另一种排序方法——插入排序(又称为不稳定排序) ,这就是同值乱序BUG的根源所在。
我们来验证一下:
先输入一共10个字符(8个大小写不同的A和两个空格字符):按以上结论应该会原样输出,通过测试。
果然是这样,然后追加一个 b,这样数组长度就超过10了,运行发现果然之前的A都乱序了。
三. 解决方案
摘出之前的sort
排序代码块