我目前正在阅读CRLS并在javascript中实现这些算法。
在第5.3节 - 通过排序进行置换,我在尝试提出简单算法的有效实现时感觉自己像个morron。这是伪代码:
这是我的实施
Array.prototype.sortShuffle = function () {
const LENGTH = this.length;
const CUBE = Math.pow(LENGTH, 3);
let P = this
.map((e, i) => {
return {v: Math.floor(Math.random() * CUBE), e: e}
})
.sort((e1, e2) => e1.v > e2.v);
P.forEach((e, i) => this[i] = e.e);
}
我使用了这个令人难过的解决方案,因为原生Array.prototype.sort没有提供比较器中的索引,A.sort((e1,e2,i1,i2)=> ...)可以已经完成了这个伎俩。
任何人都可以提供更有效的解决方案(首先不实施排序功能)
答案 0 :(得分:2)
您的代码实际上做得很好,但可以使用一些样式改进:
Array.prototype.sortShuffle = function () {
const nCubed = Math.pow(this.length, 3);
this.map(v => ({ k: Math.random() * nCubed, v }))
.sort(({ k: k1 }, { k: k2 }) => k1 - k2)
.forEach(({ v }, i) => this[i] = v);
};
特别是,您可以使用shorthand property names和object destructuring,以及删除一些不必要的变量。此外,您不需要使用Math.floor
,因为浮点数也可以正常工作。
答案 1 :(得分:1)
您可以将其他数组保持为"元组"这使得代码成为 little 清洁工。
Array.prototype.sortShuffle = function () {
return this.map(v => [Math.random() * this.length ** 3, v])
.sort(([k1,v1],[k2,v2]) => k1 - k2)
.map(([k, v]) => v);
}
就速度而言 - 您最好使用Fisher-Yates或其他O(n)
算法。
请注意,您的实现中存在错误,因为sort期望比较器函数返回正数或负数(而不仅仅是布尔值)。