我需要一个函数来改组元素数组,但是要保持元素之间的最小距离为2。
让我来解释一下我的情况,我有一个不间断的输入,该输入每200ms一直发送一次发送给我的单词。我还有一个带有预定义单词的唯一数组。
我收到的每个单词都会检查是否可以,如果在我的条件下可以,我想将其放入数组中。但是,在那一刻,我不再需要唯一的数组,所以我的数组中可能会有双精度字,实际上,我想让双精度字适合我的情况。
好的,这就是问题所在,我收到的每个OK单词,我都希望将其放入数组中,然后将其洗牌,它可以是双精度的,但是在这种情况下,我想让这个单词与数组中其他相同的词。
例:
唯一数组:[foo,bar,baz,qux]
我启动程序,每200毫秒发送一次文字给我。
获得:fubar>确定
插入:[foo,bar,baz,qux,fubar]
得到:橙色>确定
插入:[foo,bar,baz,qux,fubar,橙色]
得到:石灰>确定
插入:[foo,bar,baz,qux,fubar,橙色,酸橙]
得到:qux>确定(双)
正确插入:[foo,bar,baz,qux,fubar,橙色,石灰,qux]
正确插入:[foo,qux,bar,baz,qux,fubar,橙色,酸橙]
插入错误的方式:[foo,bar,baz,qux,qux,fubar,橙色,酸橙]
第一个距离为3,第二个距离为2 ...
第三个也是错误的,距离为0。
任何人都可以给我一个好的方法和/或逻辑来做到这一点?对于类似情况,最小距离= 2。
先感谢您。
编辑1:
用户jfriend00出现了数组充满双精度数的可能性,假设它们都具有最小距离,并且要插入的下一个元素没有合适的正确位置,那么我就不能插入它。
编辑2:
我还认为,必须避免将插入插入可能无法插入下一个插入的位置,例如:
得到:苹果>确定
(A)正确插入:[巴兹,古克斯,富巴,橙子,酸橙,苹果]
得到:qux>确定(双)
(A)正确插入:[巴兹,古克斯,富巴,橙子,古克斯,酸橙,苹果]
(B)插入错误的方式:[巴兹,古克斯,富巴,橙子,酸橙,古克斯,苹果]
在这里,插入片段将被插入距离3(B)的qux“截断”。
得到:qux>确定(双)
(A)插入正确的方式:[巴兹,古克斯,富巴,橙子,古克斯,石灰,苹果,古克斯]
(B)插入错误的方式:[巴兹,古克斯,富巴,橙子,酸橙,古克斯,苹果]
最佳答案
我必须承认,这并不简单。让我们从一些辅助函数开始:
Array.prototype.unique = function() {
var i = 0, t = 1, l = (this.length >>> 0) - 1;
for (; i < l; t = ++i + 1)
while ((t = this.indexOf(this[i], t)) !== -1)
this.splice(t, 1);
return this;
};
Array.prototype.count = function(item) {
var i = 0, t = 0;
while (i = this.indexOf(item, i) + 1) t++;
return t;
};
Array.prototype.remove = function(item) {
var i = this.indexOf(item);
if (i !== -1) this.splice(i, 1);
return this;
};
我希望含义很清楚,即使代码看起来晦涩难懂。对于较旧的浏览器(基本上是IE8-),也有用于
Array.prototype.indexOf
的polyfill。现在的代码:
function shuffleArray(array, previous) {
if (!array.length) return array;
// The list of unique items in the array
var univals = array.slice().unique(),
idx, pivot, rest;
if (previous != null)
// The array can't start with the previous element
univals.remove(previous);
while (univals.length) {
// We choose an element from the possible ones
idx = Math.floor(Math.random() * univals.length);
pivot = univals[idx];
// We try to shuffle the rest of the array.
rest = shuffleArray(array.slice().remove(pivot), pivot);
// If we got a shuffled array, we're done.
// Else, we remove our pivot element from the possible ones
if (rest != null)
return [pivot].concat(rest);
else univals.splice(idx, 1);
}
return null;
}
用法是:
shuffleArray(array);
您可以添加第二个可选参数,以使其避免从某个元素开始。在函数本身内部递归使用。如果得到
null
,则无法使用给定的约束对数组进行混洗。请记住,可以优化此算法。特别是,您可以对其进行更改,以便它不是递归的,而是迭代的,并且更适合于较大的数组。