随着假期慢慢接近,是时候再次摘下吸管了。我们总是从一个装有大家名字的盒子里挑一张纸。但是,今年我想解决使用PHP从框中选择自己名字的问题。
我有一个名为ex:
的数组$names = [
'John',
'Jane',
'Joe',
'Matt',
'Steve',
'Anne',
'Karin'
];
对于这些名字中的每一个,我想选择4个随机名称,以便最后每个人都有4个名字,他们必须为此购买礼物。
好吧,我被卡住了。我已经想到了如何做到这一点的百万种方法,但我无法想出任何东西。
array_rand()
这些的问题在于,一个人不应该选择自己的名字,并且每个人都应该被选中次数(4)。
已经发布了一些很棒的答案。我不确定这对每个人来说是否公平。最后每个人都应该从4个不同的人那里得到4份礼物。
我在考虑将每个名称添加到$names
数组4次,然后应用您的一个答案。我是否在正确的轨道上?
我现在尝试过的事情:
function select_rand($array, $exclude_array) {
$diff = array_diff($array, $exclude_array);
return $diff[array_rand($diff, 1)];
}
$workArray = [
'0' => $names,
'1' => $names,
'2' => $names,
'3' => $names,
];
foreach ($names as $k => $name) {
$i = 0;
$new[$name] = array();
while ($i < 4) {
$value = select_rand($workArray[$i], array_merge($new[$name], array($name)));
if (($key = array_search($value, $workArray[$i])) !== false) {
unset($workArray[$i][$key]);
}
$new[$name][] = $value;
$i++;
}
}
这仅适用于少数几个。
答案 0 :(得分:3)
我会使用shuffle和array_slice来完成这项工作:
$names = [
'John',
'Jane',
'Joe',
'Matt',
'Steve',
'Anne',
'Karin'
];
foreach ($names as $name) {
// working array
$working = $names;
// remove current name from array,no one wants to buy presents for him/her self..
unset($working[$name]);
shuffle($working);
$people = array_slice($working, 0, 4);
echo $name . ' has to buy presents for:';
var_dump($people);
}
答案 1 :(得分:1)
这可以提供帮助 -
function select_rand($array, $exclude_array) {
$diff= array_diff($array, $exclude_array);
return $diff[array_rand($diff, 1)];
}
$names = array(
'John',
'Jane',
'Joe',
'Matt',
'Steve',
'Anne',
'Karin'
);
foreach($names as $name)
{
$i = 0;
$new[$name] = array();
while($i < 4) {
$new[$name][] = select_rand($names, array_merge($new[$name], array($name)));
$i++;
}
}
这将为包含 4个唯一名称的数组中的每个array
(name
)生成新的key
。
<强>更新强>
$new[$name][] = select_rand($names, array_merge($new[$name], array($name, 'Karin')));
答案 2 :(得分:1)
您可以像
一样创建自定义功能$names = [
'John',
'Jane',
'Joe',
'Matt',
'Steve',
'Anne',
'Karin'
];
$my_name = "John";
$limit = 4;
function get_name($arr,$your_name,$limit){
$key = array_flip($arr)[$your_name];
unset($arr[$key]);
$rand_keys = array_rand($arr,$limit);
$result = array_intersect_key($arr, array_flip($rand_keys));
return implode(',',$result);
}
echo get_name($names,$my_name,$limit);
答案 3 :(得分:1)
我认为如果你想每人均匀分配礼物,你需要对它有更多的控制权。无论如何,在这段代码中我记录了每个人的礼物数量。我用零初始化它:$presents = array_fill_keys($names, 0);
。然后在每次选择后我更新了这个数字$presents[$key]++;
。
<?php
$names = array(
'John',
'Jane',
'Joe',
'Matt',
'Steve',
'Anne',
'Karin'
);
$presents_number = 4;
// initialization
$presents = array_fill_keys($names, 0);
$names_names = array();
foreach ($names as $i => $picker) {
$box = $names;
unset($box[$i]);
// filter out the people with maximum presents:
foreach ($presents as $key => $number) {
if (($presents[$key] > $presents_number-1) && in_array($key, $box)) {
$box = array_diff($box, array($key));
}
}
// shuffle the box and select 4 top
shuffle($box);
$selection = array_slice($box, 0, $presents_number);
foreach ($selection as $key) {
$presents[$key]++;
}
$names_names[$picker] = $selection;
}
echo "<pre>";
print_r($names_names);
echo "</pre>";
在数学上可以考虑更多。特别是因为循环可能发生,这个算法可能会出错。我没有时间花在它上面。但作为每人3人和一人的例子。 (A,B,C)
正确答案:
A =&gt; {B}
B =&gt; {C}
C =&gt; {A}
错误答案:
A =&gt; {B}
B =&gt; {A}
C =&gt; {}
基本上,完美的算法应该避免这些错误的答案。也许以后我把问题修改为这篇文章的更新。