我在找一种补槽技术。我有8个“插槽”表示为平面数组。我还有一个多维数组,其中键是主题,值是包含索引元素(时隙)的子数组。
多维数组($emp)可以包含例如在插槽1到5可用的主题Tamil和/或仅在时隙4、5或6中可用的English。所有提供的对象都将有一个可用时隙阵列--即使只有一个时隙可用。
主题提供情况:
$emp = array(
"tamil" => array(1, 2, 3, 4, 5),
"english" => array(4, 5, 6),
"maths" => array(1, 5, 8),
"social" => array(1, 2, 5),
"pt" => array(1),
"hindi" => array(3, 4, 7)
);我需要在我的输出数组($sort)中指定以下主题的确切次数--同时服从主题可用性并且没有遇到“时隙冲突”:
所有8个插槽都必须填满。所有科目只能发生一次,泰米尔语和数学除外,而泰米尔语和数学必须精确地发生两次。
产出可能是:
$slot[3] = 'tamil',
$slot[7] = 'Hindi',
$slot[6] = 'English',
$slot[1] = 'Pt',
$slot[5] = 'Maths',
$slot[8] = 'Maths',
$slot[4] = 'Tamil',
$slot[2] = 'Social'.我试过自己编码,但没有成功。
for ($i = 1; $i < 9; $i++) {
$var = $subarray[$i];
if (count($var) <= 1) {
$filledslots[$i] = $var[0];
} else {
$empty[$i] = '';
}
}
$subjects = array_flat($subarray);
$count_values = array();
$subjects = array_diff($subjects, $filledslots);
foreach ($subjects as $value) {
$count_values[$value] = 0;
foreach ($empty as $key => $val) {
$res = $subarray[$key];
if (in_array($value, $res)) {
$count_values[$value] = $count_values[$value] + 1;
}
}
if ($count_values[$value] == 1) {
//$filledslots[1] = $count_values[$value];
foreach ($empty as $key => $val) {
$res = $subarray[$key];
if (in_array($value, $res)) {
$filledslots[$key] = $value;
}
}
}
}
print_r(($filledslots)); 发布于 2020-05-08 16:24:26
下面是一种工作的递归技术,它将返回第一个限定数据集。
它的工作方式是从“必需的主题”数组和“可用插槽”数组中删除元素,同时将元素添加到“填充时隙”数组中。
使用array_replace()将限定值推入在递归调用中传递的第三个参数中,可以防止干扰$filledSlots变量的状态,该状态将继续由foreach循环使用。
功能:(演示)
function fillSlots($requiredSubjects, $availableSlots, $filledSlots = []) {
if (!$requiredSubjects) {
ksort($filledSlots);
return $filledSlots;
}
foreach ($requiredSubjects as $rIndex => $subject) {
foreach ($availableSlots[$subject] as $sIndex => $slot) {
if (!isset($filledSlots[$slot])) {
unset($requiredSubjects[$rIndex], $availableSlots[$subject][$sIndex]);
$result = fillSlots(
$requiredSubjects,
$availableSlots,
array_replace($filledSlots, [$slot => $subject])
);
if ($result) {
return $result;
}
}
}
}
}输入变量:
$subjectSlots = [
"tamil" => [1, 2, 3, 4, 5],
"english" => [4, 5, 6],
"maths" => [1, 5, 8],
"social" => [1, 2, 5],
"pt" => [1],
"hindi" => [3, 4, 7]
];
$requiredSubjects = ['tamil', 'tamil', 'pt', 'maths', 'maths', 'social', 'hindi', 'english'];为了允许函数执行数千倍快的(我对此进行了基准测试,因为我很好奇),请准备输入数据,以便先迭代较少插槽的主题。
执行前排序:(见效果)
usort($requiredSubjects, function($a, $b) use ($subjectSlots) {
return $subjectSlots[$a] <=> $subjectSlots[$b]; // sort by length, then by values
});最初的呼吁:
var_export(fillSlots($requiredSubjects, $subjectSlots));输出:
array (
1 => 'pt',
2 => 'social',
3 => 'tamil',
4 => 'tamil',
5 => 'maths',
6 => 'english',
7 => 'hindi',
8 => 'maths',
)https://stackoverflow.com/questions/61626730
复制相似问题