【问题标题】:Values not being placed in array值未放入数组
【发布时间】:2016-11-24 09:45:20
【问题描述】:

我正在为一个学校项目创建一个修订时间表,该时间表允许用户选择科目以及每个科目需要多少小时,然后将它们输入到用户可以用作表格的二维数组中。我编写了以下代码,通过上一页的帖子获取数组 $subject。

$subject 是一个二维数组,第一层是用户选择的主题,第二层是用户想要该主题的小时数。

代码应该采用 $subject 数组并在许多函数中使用它来填充数组,但是当我运行代码时,我只得到一个空数组

这里是代码

<?php
$timetable = array(

"0" => array      // 0 = Monday 6 = Sunday
    // 0 - 23 = horus
(
    "0" => '',
    "1" => '',
    "2" => '',
    "3" => '',
    "4" => '',
    "5" => '',
    "6" => '',
    "7" => '',
    "8" => '',
    "9" => '',
    "10" => '',
    "11" => '',
    "12" => '',
    "13" => '',
    "14" => '',
    "15" => '',
    "16" => '',
    "17" => '',
    "18" => '',
    "19" => '',
    "20" => '',
    "21" => '',
    "22" => '',
    "23" => ''
),
"1" => array
(
    "0" => '',
    "1" => '',
    "2" => '',
    "3" => '',
    "4" => '',
    "5" => '',
    "6" => '',
    "7" => '',
    "8" => '',
    "9" => '',
    "10" => '',
    "11" => '',
    "12" => '',
    "13" => '',
    "14" => '',
    "15" => '',
    "16" => '',
    "17" => '',
    "18" => '',
    "19" => '',
    "20" => '',
    "21" => '',
    "22" => '',
    "23" => ''
),
"2" => array
(
    "0" => '',
    "1" => '',
    "2" => '',
    "3" => '',
    "4" => '',
    "5" => '',
    "6" => '',
    "7" => '',
    "8" => '',
    "9" => '',
    "10" => '',
    "11" => '',
    "12" => '',
    "13" => '',
    "14" => '',
    "15" => '',
    "16" => '',
    "17" => '',
    "18" => '',
    "19" => '',
    "20" => '',
    "21" => '',
    "22" => '',
    "23" => ''
),
"3" => array
(
    "0" => '',
    "1" => '',
    "2" => '',
    "3" => '',
    "4" => '',
    "5" => '',
    "6" => '',
    "7" => '',
    "8" => '',
    "9" => '',
    "10" => '',
    "11" => '',
    "12" => '',
    "13" => '',
    "14" => '',
    "15" => '',
    "16" => '',
    "17" => '',
    "18" => '',
    "19" => '',
    "20" => '',
    "21" => '',
    "22" => '',
    "23" => ''
),
"4" => array
(
    "0" => '',
    "1" => '',
    "2" => '',
    "3" => '',
    "4" => '',
    "5" => '',
    "6" => '',
    "7" => '',
    "8" => '',
    "9" => '',
    "10" => '',
    "11" => '',
    "12" => '',
    "13" => '',
    "14" => '',
    "15" => '',
    "16" => '',
    "17" => '',
    "18" => '',
    "19" => '',
    "20" => '',
    "21" => '',
    "22" => '',
    "23" => ''
),
"5" => array
(
    "0" => '',
    "1" => '',
    "2" => '',
    "3" => '',
    "4" => '',
    "5" => '',
    "6" => '',
    "7" => '',
    "8" => '',
    "9" => '',
    "10" => '',
    "11" => '',
    "12" => '',
    "13" => '',
    "14" => '',
    "15" => '',
    "16" => '',
    "17" => '',
    "18" => '',
    "19" => '',
    "20" => '',
    "21" => '',
    "22" => '',
    "23" => ''
),
"6" => array
(
    "0" => '',
    "1" => '',
    "2" => '',
    "3" => '',
    "4" => '',
    "5" => '',
    "6" => '',
    "7" => '',
    "8" => '',
    "9" => '',
    "10" => '',
    "11" => '',
    "12" => '',
    "13" => '',
    "14" => '',
    "15" => '',
    "16" => '',
    "17" => '',
    "18" => '',
    "19" => '',
    "20" => '',
    "21" => '',
    "22" => '',
    "23" => ''
)
);

$subjects = $_POST;

function pick_random_subject($subjects, $timetable)
{
$available = FALSE;
while ($available == FALSE) {
    $subject = array_rand($subjects);
    if (check_subject_availability($subjects, $timetable, $subject)) {
        $available = TRUE;
    }
}
return $subject;
}

function check_subject_availability($subjects, $timetable,$subject)
{
$count = 0;
foreach ($timetable as $day) {
    $count += array_count_values($day)[$subject];
}

if ($count < $subjects[$subject]) {
    return True;
} else {
    return false;
}
}

function verify_available_slot($timetable, $day, $slot)
{
if ($timetable[$day][$slot] == '') {
    return true;
} else {
    return false;
}
}

function pick_random_slot($timetable)
{

$available = FALSE;
while ($available == FALSE) {
    $day = rand(0, 6);
    $hour = rand(0, 23);

    $available = verify_available_slot($timetable, $day, $hour);
}
return [$day, $hour];
}

function Check_end($subjects, $timetable)
{
$finished = FALSE;
foreach ($subjects as $subject) {
    if (!check_subject_availability($subjects, $timetable, $subject)) {
        $finished = TRUE;
        break;
    }
}
return $finished;
}
if(isset($_POST)) {
while(Check_end($subjects, $timetable )== FALSE)
{

$subject = pick_random_subject($subjects, $timetable);
$slot = pick_random_slot($subject);
$day = $slot[0];
$hour = $slot[1];
$timetable[$day][$hour] = $subject;
}
}
else {
header('http://localhost/timetable/TimetableAlgorithmn.php');
}

?>
<pre>
<?print_r($timetable) ?>
<pre>

注意:我认为问题出在“check_subject_availability”函数中,但我不确定。

【问题讨论】:

  • 提示:return $count &lt; $subjects[$subject];if ($count &lt; $subjects[$subject]) { return True; } else { return false; } 相同,但可读性更好,可能更快。
  • 也许您可以使用一两个 for 来创建这个巨大的结构?您拥有的代码非常庞大!

标签: php arrays function multidimensional-array


【解决方案1】:

如果没有周围的代码,我无法对其进行测试,但至少有一个问题应该存在于 Check_end()check_subject_availability 调用之间:

function Check_end($subjects, $timetable)
{
$finished = FALSE;
foreach ($subjects as $subject) {
    if (!check_subject_availability($subjects, $timetable, $subject)) {
        $finished = TRUE;
        break;
    }
}
return $finished;
}

此代码假定主题的名称是一个值,例如$subjects == ['subject1']

check_subject_availability() 中,您将其用作主题的关键,例如$subjects == ['subject1' =&gt; 5]

function check_subject_availability($subjects, $timetable,$subject)
{
$count = 0;
foreach ($timetable as $day) {
    $count += array_count_values($day)[$subject];
}

return $count < $subjects[$subject]; // usage as key
}

也许将foreach ($subjects as $subject) 更改为foreach ($subjects as $subject =&gt; $max_count) 可以解决您的问题。

另一个错误:

while(Check_end($subjects, $timetable )== FALSE)
{
    $subject = pick_random_subject($subjects, $timetable);
    list($day, $hour) = pick_random_slot($timetable);  // $timetable not $subject
    $timetable[$day][$hour] = $subject;
}

最后是最后一个错误(至少让它对我有用:)

function Check_end($subjects, $timetable)
{
$finished = TRUE;
foreach ($subjects as $subject => $max_n) {
    if (check_subject_availability($subjects, $timetable, $subject)) {
        $finished = false;
    }
}
return $finished;
}

一旦有一个主题是 !check_subject_availability(),您的版本就停止了。仅当所有主题都不可用时,此版本才会停止。

最后一个提示:您应该考虑我在下面的代码中使用的随机播放方法,因为当时间表填满并且您再也找不到空槽时,您的版本会慢慢出现问题。

一点补充:

$timetable = array_fill(0, 7, array_fill(0, 24, ''));

构造与您的 long array() 语句完全相同的数组。

更大的补充: 您的代码可以重构为:

$timetable = [];
foreach ($_POST as $subject => $n)  // add in the required amount of subjects
    $timetable = array_merge($timetable, array_fill(0, $n, $subject));
$timetable = array_merge($timetable, array_fill(0, 24 * 7 - count($timetable), ''));  // fill the array with empty values
shuffle($timetable);  // shuffle the set
$timetable = array_chunk($timetable, 24);  // split it into 7 days

【讨论】:

  • 谢谢@Christoph。这几乎完全解决了这个问题。数组现在被填充但并不总是正确的数量。例如,如果您使用 2 个科目数学(9)和物理(6)。该数组将正确填充第一个,即 9 个 maths 实例,但看似随机数量的第二个主题,即只有 1 个物理。
  • @Adam Anderson 我添加了 6 行代码,它们与您当前的代码/您想要实现的代码等效,但如果您希望我进一步搜索您的错误,请告诉我。
  • @Adam Anderson 我的答案现在包含足够的错误来使您的代码正常工作。随意接受它或提出更多问题:)
  • 非常感谢您发布的代码完美运行。我不得不将array_shuffle() 更改为shuffle()
  • @AdamAnderson 当然 ...shuffle 当然。好久没有 php 了 ;) 我希望你理解使用 shuffle 而不是 rand 的方法
猜你喜欢
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
  • 2015-02-20
  • 1970-01-01
相关资源
最近更新 更多