# [CareerCup] 8.4 Parking Lot 停车场问题

8.4 Design a parking lot using object-oriented principles.

LintCode上的原题，请参见我的另一篇博客Parking Lot 停车场问题

1. 停车场有多层，每层有多行停车位

2. 停车场可以停摩托车，小轿车和公交车

3. 停车场有摩托车位，紧凑型车位，和大型车位

4. 摩托车可以停在任何位置

5. 小轿车可以停在紧凑型车位和大型车位

6. 公交车只能停在同一行中连续的五个大型车位上，不能停在小位置上

enum class VehicleSize { Motorcycle, Compact, Large };
class Vehicle;
class Level;
class ParkingSpot {
public:
ParkingSpot(Level *lvl, int r, int n, VehicleSize s): _level(lvl), _row(r), _spotNumber(n), _spotSize(s) {} // ...
bool isAvailable() { return _vehicle == nullptr; };
bool canFitVehicle(Vehicle *vehicle) {} // ...
bool park(Vehicle *v) {} // ...
int getRow() { return _row; }
int getSpotNumber() { return _spotNumber; }
void removeVehicle() {} // ...

private:
Vehicle *_vehicle = nullptr;
VehicleSize _spotSize;
int _row;
int _spotNumber;
Level *_level = nullptr;
};

class Vehicle {
public:
Vehicle() {}
int getSpotsNeeded() { return _spotsNeeded; }
VehicleSize getSize() { return _size; }
void parkInSpot(ParkingSpot s) { _parkingSpots.push_back(s); }
void clearSpots() {} // ...
virtual bool canFitInSpot(ParkingSpot spot) {}

protected:
vector<ParkingSpot> _parkingSpots;
int _spotsNeeded;
VehicleSize _size;
};

class Bus: public Vehicle {
public:
Bus() {
_spotsNeeded = 5;
_size = VehicleSize::Large;
}
bool canFitInSpot(ParkingSpot spot) { }
};

class Car: public Vehicle {
public:
Car() {
_spotsNeeded = 1;
_size = VehicleSize::Compact;
}
bool canFitInSpot(ParkingSpot spot) { }
};

class Motorcycle: public Vehicle {
public:
Motorcycle() {
_spotsNeeded = 1;
_size = VehicleSize::Motorcycle;
}
bool canFitInSpot(ParkingSpot spot) { }
};

class Level {
public:
Level() {}
Level(int flr, int numberSpots): _floor(flr), _availableSpots(numberSpots) {}
Level(const Level* lvl) {
*this = *lvl;
}
int availableSpots() { return _availableSpots; }
bool parkVehicle(Vehicle vehicle) {} // ...
void spotFreed() { ++_availableSpots; }

private:
int _floor;
vector<ParkingSpot> _spots;
int _availableSpots = 0;
static const int _SPOTS_PER_ROW = 10;
bool parkStartingAtSpot(int num, Vehicle v) {} // ...
int findAvailableSpots(Vehicle vehicle) {} // ...
};

class ParkingLot {
public:
ParkingLot() {} // ...
bool parkVehicle(Vehicle vehicle) {} // ...

private:
vector<Level> _levels;
const int _NUM_LEVELS = 5;
};

+ 订阅