我在这里搜索了一些答案,但这似乎不是我需要的东西,或者我只是不知道如何应用它。
我还没有开始任何代码,我只想着怎么做,我不知道该怎么做。我需要你的帮助。
我们假设我有一个由下面这些值组成的数组
[1,2,3,4,5,6,7,8,9]
我需要将其洗牌而不重复最后结果的每个数字的位置。所以它可能会像
[5,3,9,6,2,8,1,4,7]
如果我再次洗牌,那就像
[4,7,2,1,8,3,6,9,5]
等等。
嗯,我不知道是否与它有任何关联,但是,宁愿不使用 rand()。这个东西有什么解决方案吗?
答案 0 :(得分:2)
试试这个,
$count = 15;
$values = range(1, $count);
shuffle($values);
$values = array_slice($values, 0, 15);
或强>
$numbers = array();
do {
$possible = rand(1,15);
if (!isset($numbers[$possible])) {
$numbers[$possible] = true;
}
} while (count($numbers) < 15);
print_r(array_keys($numbers));
这可能对你有所帮助。
答案 1 :(得分:1)
您要做的是随机地将数组中的元素添加到另一个数组,但要确保元素不在同一个索引位置。试试这个:
$array = [1,2,3,4,5,6,7,8,9];
$new = array();
for($i = 0; $i < $array.length; $i++){
$rand = $i;
do {
$rand = Math.floor( Math.random() * ( $array.length + 1 ) );
} while ($rand == $i || array_key_exists($rand, $new))
// Check that new position is not equal to current index
// and that it doesnt contain another element
$new[$rand] = $array[i];
}
效率最高,但保证将元素放在不相同的索引中。
答案 2 :(得分:1)
你可以使用Fisher-Yates-Shuffle的变体,它有偏见地随机选择被交换的元素,被称为Sattolo's algorithm:
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * i); // no +1 here!
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
这样,保证每个元素都被交换,并且不会出现在与以前相同的位置。
答案 3 :(得分:0)
这使得数组的值不会重复n次shuffle的任何先前位置(我使用数组大小的一半作为n,然后重新启动禁用索引)。最后修改了这个版本,使其不重复当前位置。
为此,您必须保存orignal数组的每个值所在的所有索引的历史记录。为此,我为您的数字增加了一点复杂性
var numberArray = [{value:1, unavailable_indexes:[0]},
{value:2, unavailable_indexes:[1]},
{value:3, unavailable_indexes:[2]},
{value:4, unavailable_indexes:[3]},
{value:5, unavailable_indexes:[4]},
{value:6, unavailable_indexes:[5]},
{value:7, unavailable_indexes:[6]},
{value:8, unavailable_indexes:[7]},
{value:9, unavailable_indexes:[8]}
];
通过这种方式,您可以获得值中的数字以及所有位置的数组。接下来我们需要运行所有数组并切换数字。
var arrayLen = numberArray.length-1;
$.each(numberArray, function(index, value){
var newIndex;
//restart the array when half of the index have been covered or it will take awhile to get a random index that wasn't used
if(value.unavailable_indexes.length >= numberArray.length/2)
value.unavailable_indexes = [index];//restart the unavailable indexes with the current index as unavailable
do{
newIndex = Math.floor(Math.random()*arrayLen);
//verify if you can swap the 2 values, if any of them have been on the destination index get another random index
}while($.inArray(value.unavailable_indexes, newIndex) || $.inArray(numberArray[newIndex].unavailable_indexes, index));
numberArray[index] = numberArray[newIndex];
numberArray[newIndex] = value;
})
在所有阵列移动后,您需要保存它们落地的位置
$.each(numberArray, function(index, value){
value.unavailable_indexes.push(index);
}
编辑:如果您只想阻止它重复上一个位置,请让unavailable_indexes
保持其所在的最后位置,并将do{...}while()
替换为:< / p>
do{
newIndex = Math.floor(Math.random()*arrayLen);
}while(newIndex != value.unavailable_indexes)
,最后一个方法如下:
$.each(numberArray, function(index, value){
value.unavailable_indexes = index;
}
答案 4 :(得分:0)
我刚刚提出了以下代码,以解决我遇到的问题,有时我的随机洗牌阵列会以其原始顺序结束(是太随机,或者不是随机够?)。
它如何工作,它循环一个while循环,直到$ isDifferent变量变为true,这只有在数组不匹配时才会发生。这可能与Fisher-Yates方法类似,但是当我尝试这种方法时,我仍然最终得到匹配的数组。
此解决方案是用PHP编写的,但可以很容易地转换为JavaScript。
guaranteedShuffle($array){
$isDifferent = false;
while(!$isDifferent){
$arrayCopy = $array;
shuffle($arrayCopy);
if($array !== $arrayCopy){
$isDifferent = true;
}
}
return $arrayCopy;
}
用法:
$array = ['1','2'];
$shuffled = guaranteedShuffle($array);
答案 5 :(得分:-1)
您可以使用Fisher Yates Shuffle
进行随机播放function fisherYates ( myArray ) {
var i = myArray.length, j, tempi, tempj;
if ( i == 0 ) return false;
while ( --i ) {
j = Math.floor( Math.random() * ( i + 1 ) );
tempi = myArray[i];
tempj = myArray[j];
myArray[i] = tempj;
myArray[j] = tempi;
}
}