【问题标题】:Fill array with values from different other arrays from different lengths用来自不同长度的不同其他数组的值填充数组
【发布时间】:2015-08-30 16:44:45
【问题描述】:

我正在尝试执行以下操作: 对于考试,我有 x 个椅子和 x 个学生。椅子可能会有所不同,人员可能会因班级和年份而异。

示例:有 112 把椅子和 102 名学生。我需要把椅子坐满,这样同年的学生就不会挨着了。

椅子并不总是排成一排,所以位置也可能不同。

我做了什么:

  • 我有两个包含椅子列的数组:$chairs1: A, D, F,... 和 $chairs2=B, E, G,... (我已经过滤了 C 行,对于示例)这样,我可以将第三年放在数组 1 中,将第四年放在数组 2 中。这样,第一年的学生不会彼此相邻
  • 我有一个数组,其中包含每年的学生人数。所以 $numberofpupilsperyear[1] = 第一年的学生人数。
  • 我有 7 个其他数组,每年一个,其中包含以下文本:$class-$examn-$classnumber。仅供参考:3Wb-English-1、3Wb-English-2、3Wb-English-3、...
  • 所有椅子的编号从 A1 到 R19。但并非所有椅子都存在于每个地方。所以我有一个带有现有椅子的数组 $allchairs[] 在那个特定的房间里检查椅子是否存在。

现在我需要用最大的 yeararray 填充最大的 chairarray。 因此,如果 $chairs1 有 80 张椅子,并且第 2 年的学生最多,则应从 $chairs1 开始填充,从第 2 年的学生开始,每年的学生人数第二多。

到目前为止我所拥有的,加上以上所有。

if($chairs1 >= $chairs2)    
{
    //fill chairs1
    $currentnumber = 1;
    $counter=0;
    while ($currentnumber < 20) 
    {   
        foreach($chairs1 as $key => $value) 
        {   
            //make coordinate of the chair
            $currentletter = $value;
            //check if chair exists
            if(in_array($currentletter.$currentnumber, $allchairs)) 
            {
                //Fill this place with a pupil like for example: 3Wb-English-1

                //But I'm a bit stuck here...
                //I was trying with the following
                $biggestyear = $number_of_students[$counter];
                echo "biggestyear: ".$biggestyear;
                ${$classlist.$biggestyear};

            }
        }
        $currentnumber++;
    }
    //now fill chairs2
    else
    {
        //fill chairs2 first and then chairs1
    }

我希望你明白我的意思...如果我需要从头重新考虑整个伪代码,请提供一些提示。

【问题讨论】:

    标签: php arrays loops foreach while-loop


    【解决方案1】:

    如果我简单地说是正确的:

    您尝试完成的是给定一个椅子网格(无论网格大小是否相同),根据班级分配学生,因此同一班级不会彼此相邻。

    在这种情况下,椅子编号/姓名、班级编号和考试都是“元数据”,不会为真正的问题添加任何内容。

    因此,我将首先设计椅子网格,其中必须可以挡住椅子(例如,指定“不可用”)。

    因为我的代码比文字更好:

    $grid = new ChairGrid(6, 18);
    
    // set non-available chairs
    $grid->get(2,5)->assigned = 'NA';
    $grid->get(1,10)->assigned = 'NA';
    
    // change names as you wish
    $grid->get(0,12)->name = 'BG1';
    
    print($grid);
    
    $pupils = array(
        1 => 20,
        2 => 30,
        3 => 20,
        4 => 20,
        5 => 20
    );
    
    // returns left-overs
    var_dump($grid->assign($pupils));
    
    print($grid);
    

    Chargrid 类:

    class ChairGrid {
        private $sizeX;
        private $sizeY;
        private $grid;
    
        public function __construct($sizeX, $sizeY) {
            $this->grid = array();
    
            $this->sizeX = $sizeX;
            $this->sizeY = $sizeY;
    
            for($x = 0; $x < $sizeX; $x++) {
                $this->grid[$x] = array();
                for($y = 0; $y < $sizeY; $y++) {
                    $chair = new Chair(chr(ord('A') + $y) . $x, $x, $y);
                    $this->grid[$x][$y] = $chair;
                }
            }
        }
    
        /**
         * @param $x
         * @param $y
         *
         * @return Chair
         */
        public function get($x, $y) {
            if (isset($this->grid[$x][$y])) {
                return $this->grid[$x][$y];
            }
    
            return null;
        }
    
        public function assign($pupils) {
            $retval = array();
    
            foreach($pupils as $class=>$number) {
                $retval[$class] = 0;
    
                $column = 0;
                $row = -1;
                for($i=0; $i < $number;$i++) {
                    $done = false;
                    while(!$done) {
                        $row++;
                        if ($row >= $this->sizeY) {
                            $row = 0;
                            $column++;
                            if ($column >= $this->sizeX) {
                                $retval[$class]++;
                                break;
                            }
                        }
    
                        $chair = $this->get($column, $row);
                        if ($chair instanceof Chair && $chair->assigned === null) {
                            // var_dump($chair->getX() . ',' . $chair->getY() . ' --?--> '.$class);
    
                            $chairLeft = $this->get($chair->x - 1, $chair->y);
                            $chairRight = $this->get($chair->x + 1, $chair->y);
                            if ($chairRight === null) {
                                $chairFirst = $this->get(0, $chair->y);
                                if ($chairLeft === null || $chairLeft->assigned !== $class) {
                                    // assign
                                    $chair->assigned = $class;
                                    $done = true;
                                }
                                else if ($chairFirst->assigned !== $class) {
                                    $prev = null;
                                    for($moveColumn = $this->sizeX - 1; $moveColumn >= 0; $moveColumn--) {
                                        $current = $this->get($moveColumn, $row);
                                        if ($current->assigned !== 'NA') {
                                            if ($prev instanceof Chair) {
                                                $prev->assigned = $current->assigned;
                                            }
    
                                            $prev = $current;
                                        }
                                    }
                                    // we cannot assign, so check "right" in first column, if we can assign, shift column
                                    $chairFirst->assigned = $class;
                                    $done = true;
                                }
                            }
                            else if (($chairLeft === null || $chairLeft->assigned !== $class) && ($chairRight === null || $chairRight->assigned !== $class)) {
                                $chair->assigned = $class;
                                $done = true;
                            }
                        }
                    }
                }
            }
    
            return $retval;
        }
    
        public function __toString() {
            $string = array();
            for($y = 0; $y < $this->sizeY; $y++) {
                $tmp = '';
                for($x = 0; $x < $this->sizeX; $x++) {
                    $tmp .= '[' . str_pad($this->grid[$x][$y]->name, 3, ' ', STR_PAD_RIGHT) . '|' . str_pad($this->grid[$x][$y]->assigned, 3, ' ', STR_PAD_RIGHT) . ']';
                }
                $string[] = $tmp;
            }
    
            return implode("\n", $string) . "\n";
        }
    }
    

    简单的椅子课:

    class Chair {
        public $name;
        public $assigned = null;
    
        public $x;
        public $y;
    
        public function __construct($name, $x, $y) {
            $this->name = $name;
            $this->x = $x;
            $this->y = $y;
        }
    }
    

    【讨论】:

    • 没错,如果我正在阅读您的评论。由于我的代码不如文字好(我只是一个业余的 PHP 编码器,不熟悉函数。真可耻!),我将尝试(和错误)并调整此代码以准确地完成如我所愿并回到它。尽管如此,这个答案似乎合乎逻辑且很有帮助。谢谢!
    【解决方案2】:

    我用一些随机数据制作了这段代码来测试它。您可以使用 fill_seats 函数并在其中添加正确的参数。

    $chairs1 = range(1, 15); //Make 5 arrays of chairs
    $chairs2 = range(16, 40);
    $chairs3 = range(41, 60);
    $chairs4 = range(61, 68);
    $chairs5 = range(69, 100);
    
    $chairs = array($chairs1,$chairs2,$chairs3,$chairs4,$chairs5); // add them to 1 array as subarrays
    
    // Fill 5 classes with students
    for($i = 1;$i <= 10; $i++){
      $year3[] = '3Wb-English-' . $i;
      if($i<8){
        $year2[] = '2Wb-English-' . $i;
      }
      if($i<7){
        $year1[] = '1Wb-English-' . $i;
      }
      if($i<9){
        $year5[] = '5Wb-English-' . $i;
      }
      if($i<6){
        $year4[] = '4Wb-English-' . $i;
      }
    }
    
    $years = array($year1,$year2,$year3,$year4,$year5); // same as chairs
    
    
    //sort the array according to the number of items in the array (biggest first)
    usort($years, 'sort_by_count');
    usort($chairs, 'sort_by_count');
    
    // Remove some chairs from all of them
    $all_chairs = range(1,100);
    unset($all_chairs[5]);
    unset($all_chairs[16]);
    unset($all_chairs[44]);
    unset($all_chairs[65]);
    unset($all_chairs[37]);
    
    // loop over them and fill in the seats (you can do this now because arrays are already sorted by count)
    foreach($years as $k => $y){
      $filled_seats[] = fill_seats($chairs[$k],$y,$all_chairs);
    }
    
    function fill_seats($chairs, $students, $all_chairs){
      $i = 0;
      foreach($chairs as $chair){
        // Seat not available
        if(!in_array($chair,$all_chairs)){
          $filled_chairs[$chair] = 'N/A';
          continue;
        }
        // Still some students left
        if(isset($students[$i])){
          $filled_chairs[$chair] = $students[$i];
        // No students left, leave them empty
        }else{ 
          $filled_chairs[$chair] = '';
        }
        $i++;
      }
      return $filled_chairs;
    }
    
    function sort_by_count($a, $b) {
        $a = count($a);
        $b = count($b);
        return ($a == $b) ? 0 : (($a > $b) ? -1 : 1);
    }
    

    结果 print_r($filled_seats):

    Array
    (
        [0] => Array
            (
                [69] => 3Wb-English-1
                [70] => 3Wb-English-2
                [71] => 3Wb-English-3
                [72] => 3Wb-English-4
                [73] => 3Wb-English-5
                [74] => 3Wb-English-6
                [75] => 3Wb-English-7
                [76] => 3Wb-English-8
                [77] => 3Wb-English-9
                [78] => 3Wb-English-10
                [79] => 
                [80] => 
                [81] => 
                [82] => 
                [83] => 
                [84] => 
                [85] => 
                [86] => 
                [87] => 
                [88] => 
                [89] => 
                [90] => 
                [91] => 
                [92] => 
                [93] => 
                [94] => 
                [95] => 
                [96] => 
                [97] => 
                [98] => 
                [99] => 
                [100] => 
            )
    
        [1] => Array
            (
                [16] => 5Wb-English-1
                [17] => N/A
                [18] => 5Wb-English-2
                [19] => 5Wb-English-3
                [20] => 5Wb-English-4
                [21] => 5Wb-English-5
                [22] => 5Wb-English-6
                [23] => 5Wb-English-7
                [24] => 5Wb-English-8
                [25] => 
                [26] => 
                [27] => 
                [28] => 
                [29] => 
                [30] => 
                [31] => 
                [32] => 
                [33] => 
                [34] => 
                [35] => 
                [36] => 
                [37] => 
                [38] => N/A
                [39] => 
                [40] => 
            )
    
        [2] => Array
            (
                [41] => 2Wb-English-1
                [42] => 2Wb-English-2
                [43] => 2Wb-English-3
                [44] => 2Wb-English-4
                [45] => N/A
                [46] => 2Wb-English-5
                [47] => 2Wb-English-6
                [48] => 2Wb-English-7
                [49] => 
                [50] => 
                [51] => 
                [52] => 
                [53] => 
                [54] => 
                [55] => 
                [56] => 
                [57] => 
                [58] => 
                [59] => 
                [60] => 
            )
    
        [3] => Array
            (
                [1] => 1Wb-English-1
                [2] => 1Wb-English-2
                [3] => 1Wb-English-3
                [4] => 1Wb-English-4
                [5] => 1Wb-English-5
                [6] => N/A
                [7] => 1Wb-English-6
                [8] => 
                [9] => 
                [10] => 
                [11] => 
                [12] => 
                [13] => 
                [14] => 
                [15] => 
            )
    
        [4] => Array
            (
                [61] => 4Wb-English-1
                [62] => 4Wb-English-2
                [63] => 4Wb-English-3
                [64] => 4Wb-English-4
                [65] => 4Wb-English-5
                [66] => N/A
                [67] => 
                [68] => 
            )
    
    )
    

    【讨论】:

    • 看起来适合 2 节课,但我还有更多。房间里可能有多达 7 个不同的班级。所以我必须将它们与所有其他类进行比较。椅子的编号是A1-Z20,所以学生们可以找到自己的位置。但我猜我仍然可以使用数组填充该函数的方式。我要测试这个!谢谢!
    • @Fl1p 只要您的椅子数组是 0 => 'A1' 到 519 => 'Z20' 就可以使用该功能。让我找到另一个问题的解决方案。
    • @Fl1p 更新了更多课程的代码(为了演示的目的,我使用了椅子的数字,因为这样更容易填充更多的椅子)。它也应该适用于字母数字椅子。
    猜你喜欢
    • 2018-07-09
    • 2020-12-31
    • 2016-03-10
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    相关资源
    最近更新 更多