假设有三个这样的数组:
$first = array('f1', 'f2', 'f3');
$second = array('s1', 's2', 's3', 's4', 's5');
$third = array('t1', 't2', 't3', 't4', 't5', 't6', 't7', 't8', 't9', 't10', 't11', 't12');
每个数组可以包含0到12个元素。任务是收集一个最多包含12个项目的数组,该数组由这三个数组中平均分布的项目组成。在这个特定的示例中,需要的输出将是:
array("f1", "f2", "f3", "s1", "s2", "s3", "s4", "t1", "t2", "t3", "t4", "t5")
所以,理想情况下,最终的数组应该有每个数组的4个元素(12个想要的元素/3个数组=每个数组的4个元素)。在上面的例子中,因为第一个数组只有3个元素,所以我通过增加其他数组中的元素来"补偿"。
我想出了这个函数:
function calcArrays($arrays, $minItems){
$finalArr = array();
$first = $arrays["first"];
$firstCount = count($first);
$second = $arrays["second"];
$secondCount = count($second);
$third = $arrays["third"];
$thirdCount = count($third);
$totalCount = $firstCount + $secondCount + $thirdCount;
if ($totalCount == 0){
return array();
}
if ($totalCount == 36){
for($i=0; $i<$minItems; $i++)
$finalArr[] = $first[$i];
for($i=0; $i<$minItems; $i++)
$finalArr[] = $second[$i];
for($i=0; $i<$minItems; $i++)
$finalArr[] = $third[$i];
return $finalArr;
}
if ($firstCount < $secondCount && $firstCount < $thirdCount){
if ($firstCount < $minItems){
for ($i=0; $i<$firstCount; $i++)
$finalArr[] = $first[$i];
}
else{
for ($i=0; $i<$minItems; $i++)
$finalArr[] = $first[$i];
}
if ($secondCount < $thirdCount){
if ($secondCount < $minItems){
for ($i=0; $i<$secondCount; $i++)
$finalArr[] = $second[$i];
}
else{
for ($i=0; $i<$minItems; $i++)
$finalArr[] = $second[$i];
}
$howManyLeftTillFull = count($arrays) * $minItems - count($finalArr);
if ($thirdCount < $howManyLeftTillFull){
for ($i=0; $i<$thirdCount; $i++)
$finalArr[] = $third[$i];
}
else{
for ($i=0; $i<$howManyLeftTillFull; $i++)
$finalArr[] = $third[$i];
}
}
else{
if ($thirdCount < $minItems){
for ($i=0; $i<$thirdCount; $i++)
$finalArr[] = $third[$i];
}
else{
for ($i=0; $i<$minItems; $i++)
$finalArr[] = $third[$i];
}
$howManyLeftTillFull = count($arrays) * $minItems - count($finalArr);
if ($secondCount < $howManyLeftTillFull){
for ($i=0; $i<$secondCount; $i++)
$finalArr[] = $second[$i];
}
else{
for ($i=0; $i<$howManyLeftTillFull; $i++)
$finalArr[] = $second[$i];
}
}
return $finalArr;
}
else if ($secondCount < $firstCount && $secondCount < $thirdCount){
//note to myself: there's gotta be a better way :/
}
else if ($thirdCount < $firstCount && $thirdCount < $secondCount){
//see the upper note to yourself and just don't go this way ^_^
}
}
,调用它们的一种方式是:
$arrays = array("first" => $first, "second" => $second, "third" => $third);
$finalArr = calcArrays($arrays, 4);
因此,我创建了第一种情况,其中第一个数组具有最少的项数,然后是第二个,最后是第三个。正如你可以在其他两个if中看到我的评论——这只是必须以一种更好、更可读的方式来完成。因为,当然,如果我继续沿着这条路走下去,我可以做到这一点,但当我重新阅读代码时,我最终会讨厌自己。
那么,有人能指出我可能存在的算法问题,或者给出一些更好的方法来解决这个问题吗?
所以,理想情况下,最终的数组应该有每个数组的4个元素(12个想要的元素/3个数组=每个数组的4个元素)。在上面的例子中,因为第一个数组只有3个元素,所以我通过增加其他数组中的元素来"补偿"。
如果存在一个开放空间,哪个数组应该填充它?您可能希望空格均匀分布,那么我建议为此编写一个完整的类,分不同的步骤计算和创建结果。
对于您的示例,如果可能的话,让下面的数组填充遗漏的空格应该是可以的。于是任务就变得相当简单了。
$data = array(
array('f1', 'f2', 'f3'),
array('s1', 's2', 's3', 's4', 's5'),
array('t1', 't2', 't3', 't4', 't5', 't6', 't7', 't8', 't9', 't10', 't11', 't12')
);
$max = 12;
$each = $max / count($data);
$result = array();
$missing = 0;
foreach ($data as $set) {
$missing += $each;
while (count($set) > 0 && $missing > 0) {
$result[] = array_shift($set);
$missing--;
}
}
print_r($result);
由于您知道$max
和输入数组的数量,因此事先计算$each
很容易。现在,只要输入数组有项目并且结果需要项目,这个while()
就会运行。如果项目的项目较少,$missing
将继续进行下一次迭代。然而,如果最后一个数组的元素太少,这可能会遇到问题,但应该给你一个想法