我试图从1-7生成一系列数字。完全随机。一个数字不能在它前面或后面有一个数字,将它除以1.
一个例子:[2,4,1,6,3,7,5]
NOT:[ 5,4 ,2, 6,7 ,1,3]。
此外, 一个数字不能包含它的位置数 (不是:[1,2,3,4,5,6,7])。
即使我在while循环中陈述了所有这些条件,它也会在不满足所有条件的情况下离开循环。我需要一些帮助来弄清楚问题是什么/更好的方法。
var randomOrder = [];
for (i = 0; i < 7; i++) {
randomOrder[i] = Math.round(Math.random() * 6 + 1);
if (i > 0) {
while ((randomOrder.lastIndexOf(randomOrder[i], i - 1) != -1) && (((randomOrder[i - 1] - 1) != randomOrder[i]) && ((randomOrder[i - 1] + 1) != randomOrder[i]) && (randomOrder[i] != (i + 1))) {
randomOrder[i] = Math.round(Math.random() * 6 + 1);
}
alert(randomOrder.lastIndexOf(randomOrder[i], i - 1));
alert(randomOrder);
}
}
答案 0 :(得分:2)
假设蛮力逼近:
var list = [ 1, 2, 3, 4, 5, 6, 7 ];
while(
list.findIndex(function(v, i) {
return v == i + 1 || (i && Math.abs(list[i - 1] - v) == 1);
}) != -1
) {
list.sort(function() { return Math.random() - 0.5; });
}
document.write(list.join(' '));
&#13;
替代版本
以下是对渐进式填充的尝试&#39;方法
总的来说,它的效率更高,因为它实际上是在尝试构建一个有效的数组,而不仅仅是观察给定的数组是否有效。它包括对不可分割情况的测试,在这种情况下它会立即中止。 build()
成功约66%的时间(实证结果),因此平均尝试次数 1.5 。
相比之下,我的第一种方法在找到有效数据之前平均生成 ~27 数组。
function build() {
var remaining = [ 1, 2, 3, 4, 5, 6, 7 ],
res = [],
candidate,
n, sz, sel;
for(n = 0; n < 7; n++) {
candidate = remaining.filter(function(v) {
return v != n + 1 && (!n || Math.abs(res[n - 1] - v) != 1);
});
if(!(sz = candidate.length)) {
return false;
}
res.push(sel = candidate[(Math.random() * sz) | 0]);
remaining.splice(remaining.indexOf(sel), 1);
}
return res;
}
while((list = build()) === false) {};
document.write(list.join(' '));
&#13;
答案 1 :(得分:0)
我会考虑的方法概要:
对于每个位置,计算该位置的可能数字集,并从该列表中随机选择。
位置0该组将是[2 ... 7],在位置1,它将是[1,3 ... 7]减去由于在位置0处的选择而被移除的那些。
如果失败从头开始重新启动,直到它没有(如果某个位置的可能性集为空,则失败)。
答案 2 :(得分:0)
我认为主要问题是使用&amp;&amp; (AND)而不是|| (OR)。
var result = [], current, last = Infinity, i;
while (result.length < 7) {
i = 0;
while(++i < 1000 && (!current || result.includes(current) || (current === last - 1) || (current === last + 1) || (current === result.length))) {
current = 1 + (Math.random() * 7) | 0; // use your floor of choice
}
if (i >= 1000) { result.length = 0; continue; }
result.push(current);
last = current;
}
答案 3 :(得分:-1)
您的代码缺失了)。 这是一个正确循环的固定版本:
var randomOrder = [];
for (i = 0; i < 7; i++) {
randomOrder[i] = Math.round(Math.random() * 6 + 1);
if (i > 0) {
while ((randomOrder.lastIndexOf(randomOrder[i], i - 1) != -1) && (((randomOrder[i - 1] - 1) != randomOrder[i]) && ((randomOrder[i - 1] + 1) != randomOrder[i]) && (randomOrder[i] != (i + 1)))) {
randomOrder[i] = Math.round(Math.random() * 6 + 1);
}
alert(randomOrder.lastIndexOf(randomOrder[i], i - 1));
alert(randomOrder);
}
}