美文网首页
[OOD]Parking Spot

[OOD]Parking Spot

作者: 瞬铭 | 来源:发表于2019-04-16 21:43 被阅读0次

    Parking Spot

    设计一个停车场
    这道题让我们实现一个停车位的数据结构,由于题目没给任何多余的信息,所>以自由度很大,比如能停放什么种类的车,或是否是多层的等等。根据书中描>述,这里我们做如下假设:

    1. 停车场有多层,每层有多行停车位
    2. 停车场可以停摩托车,小轿车和公交车
    3. 停车场有摩托车位,紧凑型车位,和大型车位
    4. 摩托车可以停在任何位置
    5. 小轿车可以停在紧凑型车位和大型车位
    6. 公交车只能停在同一行中连续的五个大型车位上,不能停在小位置上
    • 停车位ParkingSpot类,一个停车场ParkLot由多个停车层Level组成,一个Level由多个ParkingSpot组成
    • 基类Vehicle,机动车,可以被继承,具体实例化为motocycle,car,truck
      大小,需要的停车位,停车入库,是否合适这个spot
    • 停车层Level类,ParkingSpot类的集合
      还剩多少停车位,停车入库function(包括判断车位是否充足,找到应该停在哪个车位,停进去三部曲)
      参考链接:https://blog.csdn.net/xjwun/article/details/43484327
    <?php
    
    class ParkingSpot {
    
        private $vehicle;
    
        private $spotSize;
    
        private $row;
    
        private $spotNum;
    
        private $level;
    
        /**
         * ParkingSpot constructor.
         * @param Level $lvl 层数
         * @param $r  第几列
         * @param $n  spot numer,一个标示
         * @param $size spot的大小
         */
        public function __construct(Level $lvl, $r, $n, $size) {
            $this->level    = $lvl;
            $this->row      = $r;
            $this->spotNum  = $n;
            $this->spotSize = $size;
            //vehicle初始为null,因为没停车
        }
    
        /**
         * isAvailable
         * @return bool
         * @brief 判断当前spot是否可用
         */
        public function isAvailable() {
            return $this->vehicle == null;
        }
    
        /**
         * canFitVehicle
         * @param Vehicle $vehicle
         * @return bool
         */
        public function canFitVehicle(Vehicle $vehicle) {
            return $this->isAvailable() && $vehicle->canFitInSpot($this);
        }
    
        /**
         * park
         * @param Vehicle $v
         * @return bool
         * @brief 停车入库
         */
        public function park(Vehicle $v) {
            if (!$this->canFitVehicle()) {
                return false;
            }
            $v->parkInSpot($this);
            return true;
        }
    
        /**
         * removeVehicle
         * @return void
         * @brief 出库
         */
        public function removeVehicle() {
            //todo
            $this->level->spotFreed();
            $this->vehicle = null;
        }
    
        public function getRow() {
            return $this->spotNum;
        }
    
        public function getSize() {
            return $this->spotSize;
        }
    }
    
    
    class Level {
        private $floor;
    
    
        private $spots;//parkingpot 的集合
    
        private $availableSpots = 0;
    
        const SPOTS_PER_ROW = 10;
    
        public function __construct($floor, $spotsnum) {
            $this->floor = $floor;
            $this->spots = [];//理论上这里的array要申明长度为spotsnum
        }
    
    
        /**
         * parkVehicle
         * @param Vehicle $vehicle
         * @return bool
         * @brief 停车入位
         */
        public function parkVehicle(Vehicle $vehicle) {
    
            // 车位不足
            if ($this->availableSpots < $vehicle->getSpotsNeeded()) {
                return false;
            }
    
            //这里的spotNum是spots这个array的索引,并不是spots类里面的spotNum
            $spotNum = $this->findAvailableSpots($vehicle);
            if ($spotNum < 0) {
                return false;
            }
    
            return $this->parkStartingAtSpot($spotNum, $vehicle);
        }
    
        /**
         * findAvailableSpots
         * @param Vehicle $vehicle
         * @return int spots的索引$i
         * @brief 查找是否有车位能符合这辆车
         *
         */
        public function findAvailableSpots(Vehicle $vehicle) {
            $spotNeeded = $vehicle->getSpotsNeeded();
            $lastRow    = -1;
            $spotsFound = 0;
            for ($i = 0; $i < count($this->spots); $i++) {
                $spot = $this->spots[$i];//spot 为一个Parking Spot
    
                //换行则重新计算
                if ($lastRow != $spot->getRow()) {
                    $spotsFound = 0;
                    $lastRow    = $spot->getRow();
                }
    
                //canFitVehicle 只判断size是否合适,(类似一个truck需要5个spot,所以需要循环)
                if ($spot->canFitVehicle(vehicle)) {
                    $spotsFound++;
                } else {
                    $spotsFound = 0;
                }
    
                if ($spotsFound == $spotNeeded) {
                    return $i - ($spotNeeded - 1);//index of spot
                }
            }
            return -1;
        }
    
        /**
         * parkStartingAtSpot
         * @param $spotNum
         * @param Vehicle $vehicle
         * @return bool
         */
        private function parkStartingAtSpot($spotNum, Vehicle $vehicle) {
            $vehicle->clearSpots();
            $success = true;
    
            for ($i = $spotNum; $i < $spotNum + $vehicle->getSpotsNeeded(); $i++) {
                $success &= $this->spots[$i]->park($vehicle);
            }
            $this->availableSpots -= $vehicle->getSpotsNeeded();
            return $success;
        }
    
        public function spotFreed() {
            $this->availableSpots++;
        }
    
        /**
         * availableSpots
         * @return int
         * @brief 返回当前可用spot的数量
         */
        public function availableSpots() {
            return $this->availableSpots;
        }
    }
    
    class Vehicle {
    
        protected $size;
    
        protected $license;//car license id
    
        protected $spotNeed;
    
        protected $parkingSpots = [];//一个车可能停在多个spot上面,所以是array
    
        protected $vehicleSize = [
            "motocycle" => 1,
            "car"       => 2,
            "truck"     => 3,
        ];
    
        public function __construct() {
    
        }
    
        public function getSize() {
            return $this->size;
        }
    
        public function getSpotsNeeded() {
            return $this->spotNeed;
        }
    
        /**
         * parkInSpot
         * @param ParkingSpot $spot
         * @return void
         * @brief 停车入库
         */
        public function parkInSpot(ParkingSpot $spot) {
            $this->parkingSpots[] = $spot;
        }
    
        /**
         * clearSpots
         * @return void
         */
        public function clearSpots() {
            $this->parkingSpots = [];
        }
    
        public function canFitInSpot(ParkingSpot $spot) {
    
        }
    }
    
    class Motocycle extends Vehicle {
        public function __construct() {
            $this->spotNeed = 1;
            $this->size     = $this->vehicleSize['motocycle'];
        }
    
        /**
         * canFitInSpot
         * @param ParkingSpot $spot
         * @return bool|void
         */
        public function canFitInSpot(ParkingSpot $spot) {
            return true;
        }
    }
    
    class Car extends Vehicle {
    
        /**
         * Car constructor.
         */
        public function __construct() {
            $this->spotNeed = 1;
            $this->size     = $this->vehicleSize['car'];
        }
    
        /**
         * canFitInSpot
         * @param ParkingSpot $spot
         * @return bool|void
         * @brief
         */
        public function canFitInSpot(ParkingSpot $spot) {
            return ($spot->getSize() == $this->vehicleSize['car']) || ($spot->getSize() == $this->vehicleSize['truck']);
        }
    }
    
    class Truck extends Vehicle {
        public function __construct() {
            $this->spotNeed = 5;
            $this->size     = $this->vehicleSize['truck'];
        }
    
        /**
         * canFitInSpot
         * @param ParkingSpot $spot
         * @return bool|void
         * @biref 只判断能不能停,
         */
        public function canFitInSpot(ParkingSpot $spot) {
            return $spot->getSize() == $this->vehicleSize['truck'];
        }
    }
    
    
    class ParkingLot {
        private $levels;
    
        const NUM_LEVELS = 5;
    
        /**
         * ParkingLot constructor.
         *
         */
        public function __construct() {
            $this->levels = [];
            for ($i = 0; $i < self::NUM_LEVELS; $i++) {
                $this->levels[$i] = new Level($i, 30);
            }
    
        }
    
        public function parkVehicle(Vehicle $vehicle){
            for($i = 0;$i<count($this->levels);$i++){
                if($this->levels[$i]->parkVehicle[$vehicle]){
                    return true;
                }
            }
            return false;
        }
    }
    

    相关文章

      网友评论

          本文标题:[OOD]Parking Spot

          本文链接:https://www.haomeiwen.com/subject/tqoiwqtx.html