首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在没有冲突的情况下根据密钥可用性将所有输入值赋值到数组中?

如何在没有冲突的情况下根据密钥可用性将所有输入值赋值到数组中?
EN

Stack Overflow用户
提问于 2020-05-06 03:13:58
回答 1查看 174关注 0票数 3

我在找一种补槽技术。我有8个“插槽”表示为平面数组。我还有一个多维数组,其中键是主题,值是包含索引元素(时隙)的子数组。

多维数组($emp)可以包含例如在插槽1到5可用的主题Tamil和/或仅在时隙4、5或6中可用的English。所有提供的对象都将有一个可用时隙阵列--即使只有一个时隙可用。

主题提供情况:

代码语言:javascript
运行
复制
$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)中指定以下主题的确切次数--同时服从主题可用性并且没有遇到“时隙冲突”:

  • 泰米尔2次
  • PT 1次
  • 数学2次
  • 社交1次
  • 印地语1次
  • 英语1次

所有8个插槽都必须填满。所有科目只能发生一次,泰米尔语和数学除外,而泰米尔语和数学必须精确地发生两次。

产出可能是:

代码语言:javascript
运行
复制
$slot[3] = 'tamil',
$slot[7] = 'Hindi', 
$slot[6] = 'English',
$slot[1] = 'Pt',
$slot[5] = 'Maths',
$slot[8] = 'Maths',
$slot[4] = 'Tamil',
$slot[2] = 'Social'.

我试过自己编码,但没有成功。

代码语言:javascript
运行
复制
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)); 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-08 16:24:26

下面是一种工作的递归技术,它将返回第一个限定数据集。

它的工作方式是从“必需的主题”数组和“可用插槽”数组中删除元素,同时将元素添加到“填充时隙”数组中。

使用array_replace()将限定值推入在递归调用中传递的第三个参数中,可以防止干扰$filledSlots变量的状态,该状态将继续由foreach循环使用。

功能:(演示)

代码语言:javascript
运行
复制
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;
                }
            }
        }
    }
}

输入变量:

代码语言:javascript
运行
复制
$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'];

为了允许函数执行数千倍快的(我对此进行了基准测试,因为我很好奇),请准备输入数据,以便先迭代较少插槽的主题。

执行前排序:(见效果)

代码语言:javascript
运行
复制
usort($requiredSubjects, function($a, $b) use ($subjectSlots) {
    return $subjectSlots[$a] <=> $subjectSlots[$b];  // sort by length, then by values
});

最初的呼吁:

代码语言:javascript
运行
复制
var_export(fillSlots($requiredSubjects, $subjectSlots));

输出:

代码语言:javascript
运行
复制
array (
  1 => 'pt',
  2 => 'social',
  3 => 'tamil',
  4 => 'tamil',
  5 => 'maths',
  6 => 'english',
  7 => 'hindi',
  8 => 'maths',
)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61626730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档